@cocreate/authenticate
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -0,1 +1,8 @@ | ||
## [1.0.5](https://github.com/CoCreate-app/CoCreate-authenticate/compare/v1.0.4...v1.0.5) (2023-06-10) | ||
### Bug Fixes | ||
* Update dependencies versions for [@cocreate](https://github.com/cocreate) libraries ([4f8053a](https://github.com/CoCreate-app/CoCreate-authenticate/commit/4f8053ab55494485b6b51af851a8ed95777d6947)) | ||
## [1.0.4](https://github.com/CoCreate-app/CoCreate-authenticate/compare/v1.0.3...v1.0.4) (2023-06-04) | ||
@@ -2,0 +9,0 @@ |
module.exports = { | ||
"config": { | ||
"key": "2061acef-0451-4545-f754-60cf8160", | ||
"organization_id": "5ff747727005da1c272740ab", | ||
"host": "general.cocreate.app" | ||
}, | ||
"organization_id": "", | ||
"key": "", | ||
"host": "", | ||
"sources": [ | ||
@@ -8,0 +6,0 @@ { |
{ | ||
"name": "@cocreate/authenticate", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "A simple authenticate component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.", | ||
@@ -26,3 +26,4 @@ "keywords": [ | ||
"build": "NODE_ENV=production npx webpack --config webpack.config.js", | ||
"docs": "node ./node_modules/@cocreate/docs/src/index.js" | ||
"docs": "node ./node_modules/@cocreate/docs/src/index.js", | ||
"postinstall": "node ./node_modules/@cocreate/cli/check-coc.js" | ||
}, | ||
@@ -43,7 +44,10 @@ "publishConfig": { | ||
"homepage": "https://cocreate.app/docs/authenticate", | ||
"devDependencies": { | ||
"@cocreate/cli": "^1.29.3" | ||
}, | ||
"dependencies": { | ||
"@cocreate/docs": "^1.7.15", | ||
"@cocreate/uuid": "^1.4.13", | ||
"@cocreate/docs": "^1.8.13", | ||
"@cocreate/uuid": "^1.4.15", | ||
"jsonwebtoken": "^9.0.0" | ||
} | ||
} |
191
src/index.js
@@ -1,102 +0,125 @@ | ||
const jwt = require("jsonwebtoken") | ||
const uid = require("@cocreate/uuid") | ||
const jwt = require('jsonwebtoken'); | ||
class CoCreateAuthenticate { | ||
/** | ||
* config structure | ||
* https://www.npmjs.com/package/jsonwebtoken | ||
{ | ||
key: 'xxxxxx', // any value | ||
options: { | ||
algorithm: "HS256", | ||
expiresIn: "30m", | ||
issuer: "issuer" | ||
} | ||
} | ||
**/ | ||
// Configuration | ||
const tokenExpiration = 60; // Token expiration in minutes | ||
// Array to store key pairs | ||
const keyPairs = new Map(); | ||
constructor(config) { | ||
this.config = config | ||
this.config['key'] = uid.generate(40) | ||
} | ||
// Map to store authenticated user | ||
const users = new Map(); | ||
async generateToken({ user_id }) { | ||
try { | ||
const { key, options } = this.config | ||
const result = { | ||
token: jwt.sign({ user_id }, key, options), | ||
} | ||
return result.token; | ||
} catch (err) { | ||
return null | ||
} | ||
} | ||
// TODO: user can have multiple sessions | ||
const activeSessions = new Map(); | ||
async getUserId(req) { | ||
try { | ||
let { user_id } = await this.wsCheck(req) | ||
return user_id | ||
} catch (err) { | ||
return null | ||
} | ||
} | ||
// crud.listen('createDocument', function (data) { | ||
// if (data.document && data.document[0] && data.document[0].type === 'keyPair') | ||
// keyPairs.set(data.document[0]._id, data.document[0]); | ||
// }); | ||
getTokenFromCookie(cookie) { | ||
let token = null; | ||
if (cookie) { | ||
cookie.split(';').forEach((c) => { | ||
try { | ||
var parts = c.split('=') | ||
if (parts[0].trim() == 'token') { | ||
token = decodeURI(parts[1].trim()); | ||
} | ||
} catch (err) { | ||
console.log(err) | ||
} | ||
}) | ||
} | ||
return token; | ||
} | ||
// crud.listen('deleteDocument', function (data) { | ||
// if (data.document && data.document[0] && data.document[0].type === 'keyPair') | ||
// keyPairs.delete(data.document[0]._id); | ||
// }); | ||
async wsCheck(req) { | ||
const headers = req.headers | ||
let token = headers['sec-websocket-protocol']; | ||
// let token = this.getTokenFromCookie(headers.cookie); | ||
// if (!token) { | ||
// token = headers['sec-websocket-protocol']; | ||
// } | ||
// Create new RSA key pair | ||
function createKeyPair() { | ||
const { privateKey, publicKey } = jwt.generateKeyPairSync('rsa', { | ||
modulusLength: 2048, | ||
}); | ||
let result = null; | ||
if (token && token !== 'null') { | ||
result = await this.verifiyToken(token); | ||
} | ||
const keyPair = { | ||
_id: crud.ObjectId(), | ||
privateKey, | ||
publicKey, | ||
created: new Date().getTime(), // Store as timestamp | ||
expires: new Date().getTime() + tokenExpiration * 60 * 1000 * 2, // Convert minutes to milliseconds | ||
}; | ||
return result; | ||
} | ||
keyPairs.set(keyPair._id, keyPair); | ||
async httpCheck(req) { | ||
// crud.createDocument({ | ||
// collection: 'keys', | ||
// document: { | ||
// ...keyPair, | ||
// }, | ||
// organization_id: process.env.organization_id, | ||
// }); | ||
return keyPair; | ||
} | ||
// Function to retrieve keys from the database (example using CRUD operations) | ||
function readKeyPairs() { | ||
const keys = crud.readDocument({ | ||
collection: 'keys', | ||
filter: { | ||
query: [ | ||
{ name: 'type', value: 'keyPair' }, | ||
], | ||
}, | ||
organization_id: process.env.organization_id, | ||
}); | ||
// Add retrieved key pairs to the keyPairs array | ||
if (keys.document && keys.document.length) { | ||
keys.document.forEach((keyPair) => { | ||
keyPairs.set(keyPair._id, keyPair); | ||
}); | ||
} | ||
} | ||
async verifiyToken(token) { | ||
try { | ||
let decoded = await jwt.verify(token, this.config.key) | ||
return decoded; | ||
} catch (err) { | ||
if (err.message === 'jwt expired') { | ||
console.log('Expired Token') | ||
return null | ||
} else if (err.message === 'invalid token') { | ||
console.log('Invalid Token') | ||
return null | ||
} else { | ||
console.log('Invalid token', token) | ||
return null; | ||
} | ||
// Delete new RSA key pair | ||
function deleteKeyPair(keyPair) { | ||
keyPairs.delete(keyPair._id) | ||
// crud.deleteDocument({ | ||
// collection: 'keys', | ||
// document: { | ||
// _id: keyPair._id, | ||
// type: 'keyPair' | ||
// }, | ||
// organization_id: process.env.organization_id, | ||
// }); | ||
} | ||
// Function to sign a new token using the newest keyPair | ||
function encodeToken(payload) { | ||
let keyPair = null | ||
const currentTime = new Date().getTime(); | ||
for (let [key, value] of keyPairs) { | ||
if (currentTime > value.expires) { | ||
deleteKeyPair(value); | ||
} else { | ||
keyPair = value | ||
} | ||
} | ||
if (!keyPair) { | ||
keyPair = createKeyPair(); | ||
} | ||
// TODO: payload could have previous user ip and device information which we could use to comapre to current ip and device information | ||
const token = jwt.sign(payload, keyPair.privateKey, { expiresIn: tokenExpiration * 60 }); | ||
users.set(token, { _id: payload.user._id, expires: new Date().getTime() + tokenExpiration * 60 * 1000 }) | ||
return token; | ||
} | ||
module.exports = CoCreateAuthenticate; | ||
// Verify and decode a token using the available keys | ||
function decodeToken(req) { | ||
const headers = req.headers; | ||
const token = headers['sec-websocket-protocol']; | ||
const currentTime = new Date().getTime(); | ||
let user = users.get(token) | ||
if (user && currentTime < user.expires) | ||
return user._id; | ||
users.delete(token) | ||
return null | ||
} | ||
// readKeyPairs(); | ||
module.exports = { encodeToken, decodeToken }; |
Sorry, the diff of this file is not supported yet
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
61680
145
1
1
1
Updated@cocreate/docs@^1.8.13
Updated@cocreate/uuid@^1.4.15