1.0.0 • Published 5 years ago

jrfjwt v1.0.0

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

JRFJWT

jrfjwt is an async/await package for working with JWT. The functional uses one of PostgreSQL or MongoDB DBMS. Work with tokens is conducted in the context of User, Device.

installation

$ nmp -i jrfjwt

Token content

access and refresh tokens contain

  • head head: {alg, typ}

    NameTypeDescription
    algstringEncryption algorithm
    typstringToken type
  • payload head: {userId, rolesId, devId, iss, exp}

    NameTypeDescription
    userIdstringuser id
    rolesIdarray of stringuser role id
    devIdstringuser device id
    issstringID of the token-generating side
    expnumberToken lifetime

methods

constructor()

Just creates an object const jrfjwt = new JRFJWT();

init(options)

Initialization let res = await jrfjwt.init(options)

  • Options - the jrfjwt setting consists of the db database setting and token token setting. You can initialize without options, then the default settings will be applied.

  • db

NameTypeDefault valueDescription
typestringjrfjwt.dbType.MongoDBWhat DBMS to use for storing tokens. To use MongoDB type: jrfjwt.dbType.MongoDB or type: 'mongoDB'. To use PostgreSQL type: jrfjwt.dbType.PostgreSQL or type: 'postgreSQL'
serverstring'localhost'DBMS Address
portnumberMongoDB port: 27100. PostgreSQL port: 5432DBMS Port
dbstring'jrfjwt'Database name in DBMS
collectionstring'jwt'Collection name, for MongoDB only
userstring''DBMS username. The user must be the owner of the database.
passwordstring''DBMS User Password
  • token
NameTypeDefault valueDescription
algstring'HS512'Encryption algorithm
typstring'JWT'Token type
issstring''ID of the token-generating side
accessExpstring'10min'Access Token lifetime. Available are ms, sec, min, hour, day
refreshExpstring'10day'Refresh Token lifetime. Available are ms, sec, min, hour, day
saltstring'J*$#d84'Salt
iterationsnumber100Number of iterations
hashLengthnumber64Hash length
  • Example
    const JRFJWT = require('jrfjwt');
    const jrfjwt = new JRFJWT();
    
    let res = await jrfjwt.init({
        db: {
            type: jrfjwt.dbType.PostgreSQL,
            server: 'localhost',
            port: 5432,
            db: 'jrfjwt_test',
            user: 'jrfjwttest',
            password: '12345678'
        },
        token: {
            alg: 'HS512',
            typ: 'JWT',
            iss: '',
            accessExp: '10min',
            refreshExp: '10day',
            salt: 'J*$#d73',
            iterations: 100,
            hashLength: 64
        }
    });
  • Response - If it was not possible to connect to the database, a 'not init jrfjwt' exception will be thrown.
res.okayres.descriptionres.outputDescription
true''empty arrayInitialization went well

addNewUser(user)

Add a new user to the database of tokens.

  • user
NameTypeoptionalDescription
userIdstringUser id
rolesIdarray of stringstrueArray id user roles
  • Example
    let res = await jrfjwt.addNewUser({
        userId: 'morty',
        rolesId: ['yong', 'foreveryong']
    });
  • Response
res.okayres.descriptionres.outputDescription
true''idUser has been added. If MongoDB then output [0] contains the internal id of the added document 5c739e5cff97723bbc43bd9b. If PostgreSQL then output [0] contains the userId of the added user morty
false'not add'emptyUser failed to add.

addNewUsers(users)

Add new users to the database of tokens.

  • users - array containing users

  • user

NameTypeoptionalDescription
userIdstringUser id
rolesIdarray of stringstrueArray id user roles
  • Example
    let res = await jrfjwt.addNewUsers([
        {
            userId: 'morty',
            rolesId: ['yong', 'foreveryong']
        },
        {
            userId: 'rick',
            rolesId: ['space', 'superspace']
        }
    ]);
  • Response
res.okayres.descriptionres.outputDescription
true''array of res add userres.okay always true. The array res.output contains the results of the addition for each user
  • res add user
NameTypeDescription
userobjadd user
addbooleantrue - user added, false - failed to add user
descriptionstringuserId - if a user is added, 'not add' - if unable to add a user

getUsers(id)

Get users, if id is not passed, all users are returned.

  • id
NameTypeoptionalDescription
idstringtrueUser id
  • Example
    let res = await jrfjwt.getUsers();
  • Response
res.okayres.descriptionres.outputDescription
true''array of usersoutput [0] contains user (s)
  • user
NameTypeDescription
userIdstringuser id
rolesIdarray of stringarray of user roles id
tokensarray of tokenarray of active user tokens
tokensOldarray of tokenOldarray of obsolete user tokens
  • token
NameTypeDescription
devIdstringuser device id
accessstringaccess token
refreshstringrefresh token
[ { userId: 'morty',
       rolesId: [ 'yong', 'foreveryong' ],
       tokens:
        [ { devId: 'blaster',
            access: 'accessToken1',
            refresh: 'refreshToken1' },
          { devId: 'laser',
            access: 'accessTokenLaser',
            refresh: 'refreshTokenLaser' },
          { devId: 'loser',
            access: 'accessTokenLoser',
            refresh: 'refreshTokenLoser' } ],
       tokensOld:
        [ { devId: 'blaster',
            access: 'accessToken1Old',
            refresh: 'refreshToken1Old' },
          { devId: 'laser',
            access: 'accessTokenLaserOld',
            refresh: 'refreshTokenLaserOld' },
          { devId: 'Cheat',
            access: 'accessTokenCheaatOld',
            refresh: 'refreshTokenCheatOld' } ] } ]

updateRoles(userId, rolesId)

Update user roles

NameTypeoptionalDescription
userIdstringuser id
rolesIdarray of stringstruearray of user role id; if the array is not set, then all user roles will be deleted from the user
  • Example
    let res = await jrfjwt.getUsers('morty', ['user', 'guest']);
  • Response
res.okayres.descriptionres.outputDescription
true''emptyRoles updated
false'not update'emptyRoles not updated

delUsers(id)

Delete user, if id is not passed, all users are deleted.

  • id
NameTypeoptionalDescription
idstringtrueuser id
  • Example
    let res = await jrfjwt.delUsers();
  • Response
res.okayres.descriptionres.outputDescription
true'deleted: X'array of usersManaged to delete user (s). Where X is the number of deleted users. res.output if MongoDB, then contains the number of remote users, if PosgreSQL, it contains objects of remote users
false''emptyCould not delete

createTokens(userId)

Create a new token for user

NameTypeDescription
userIdstringuser id
  • Example
    let res = await jrfjwt.createTokens('morty');
  • Response
res.okayres.descriptionres.outputDescription
true''tokenoutput[0] contains the created token
false'not create'emptyFailed to create a new token.
  • token
NameTypeDescription
devIdstringgenerated device id
accessstringaccess token
refreshstringrefresh token

updateTokens(userId, devId)

Update (reissue) user token for device.

NameTypeDescription
userIdstringuser id
devIdstringdevice id
  • Example
    let res = await jrfjwt.updateTokens('morty', 'DKO32LS');
  • Response
res.okayres.descriptionres.outputDescription
true''tokenoutput[0] contains the updated token
false'not update'emptyFailed to update token
  • token
NameTypeDescription
devIdstringuser id
accessstringaccess token
refreshstringrefresh token

delTokens(userId, devId)

Delete user device token.

NameTypeDescription
userIdstringuser id
devIdstringdevice id
  • Example
    let res = await jrfjwt.delTokens('morty', 'DKO32LS');
  • Response
res.okayres.descriptionres.outputDescription
true''emptyToken removed
false'not del'emptyCould not delete token

delAllTokens(userId)

Delete all user tokens.

NameTypeDescription
userIdstringuser id
  • Example
    let res = await jrfjwt.delAllTokens('morty');
  • Response
res.okayres.descriptionres.outputDescription
true''emptyTokens removed
false'not del'emptyCould not remove tokens

isValid(access, refresh, rolesRules, usersRules)

Check token for validity. Check user access rights.

NameTypeoptionalDescription
accessstringaccess user token
refreshstringrefresh user token
rolesRulesobjtrueRole Access Validation Rules
usersRulesobjtrueUser Access Verification Rules
  • rolesRules
NameTypeoptionalDescription
excludearray of stringsarray of id roles that are denied access
includearray of stringsarray id roles allowed access
defaultAccessbooleandefault access if the role is not found in any of the lists. true - access is allowed, false - access is denied
  • usersRules
NameTypeoptionalDescription
excludearray of stringsarray id users who are denied access
includearray of stringsArray id of users who are allowed access
defaultAccessbooleandefault access if users are not found in any of the lists. true - access is allowed, false - access is denied
  • Example
const rolesRules = {
            exclude: ['superuser'],
            include: [],
            defaultAccess: false
        };
let res = await token.isValid({access, refresh, rolesRules});
  • Logic

    • Tokens are decoded; if decode failed, then return res.description = 'invalid'
    • The access token's signature is checked, if the signature is not valid, then return res.description = 'access signature invalid'
    • The refresh token's signature is checked, if the signature is not valid, then the return is res.description = 'refresh signature invalid'
    • Search user userId in the database, if the user is not found, then returnres.description = 'not found user'
    • Search access andrefresh tokens from user by devId.

      At one time, a user by devId can have only one valid token (token: {devId, access, refresh}) and one obsolete/previous token (tokenOld: {devId, access, refresh}).

      If the access andrefresh tokens are not found in the token and tokenOld, then return res.description = 'tokens not found', the tokens by userId, devId are removed

    • If the access and refresh tokens were found in tokenOld, then tokenOld is deleted, and access and refresh take on the value from token (token: {devId, access, refresh} tokenOld : {}).

    • It checks the lifetime of the refresh token, if the lifetime has expired, then return res.description = 'refresh token not live', tokens are deleted by userId, devId
    • The access time of the access token is checked, if the lifetime has expired, the user creates a new token: {devId, access, refresh}, removes tokenOld: {}, the current access and refresh tokens are placed in tokenOld: {devId, access, refresh}. A new token is passed in the response res.tokensNew. If an error occurred while updating the token, then return res.description = 'server error, repeat pleas'
    • If usersRules was passed, then it is checked whether access is allowed to the user. If userId is found in include, then res.access = true, if userId is found in exclude, then res.access = false, if userId is not found in include and in exclude, then res.access = defaultAccess. If res.access = false, then return res.description = 'no rights'
    • If rolesRules was passed, then it is checked whether access to the user is allowed by roles. If one of the roles of the user rolesId is found in include, then res.access = true, if one of the user roles of the rolesId is found in exclude, then res.access = false, if none of user roles rolesId not found in include and in exclude, then res.access = defaultAccess. If res.access = false, then return res.description = 'no rights'
    • Return response res
      res = {
          okay: true,
          description: '',
          isValid: true,
          access: true,
          tokensNew: {devId, access, refresh}
      };
  • Response

res.okayres.descriptionres.isValidres.accessres.tokensNewDescription
false'invalid'falsefalseundefinedInvalid token failed to decode
false'access signature invalid'falsefalseundefinedNot valid token access signature
false'refresh signature invalid'falsefalseundefinedNot valid refresh token signature
false'not found user'falsefalseundefinedUser is not found, tokens are deleted by userId, devId
false'tokens not found'falsefalseundefinedThe access and refresh tokens are not found in tokens and tokensOld by userId, devId, tokens are deleted by userId, devId
false'refresh token not live'falsefalseundefinedThe refresh token has expired, the tokens are deleted by userId, devId
false'server error, repeat pleas'falsefalseundefinedThe token access lifetime has expired. An error occurred on the server while trying to update the token.
true'no rights'truefalseundefinedToken is valid, but there is no access by user or by role.
true''truetrueundefinedToken valid, there is access
true''truetrue{devId, access, refresh}Token valid, there is access. Token updated.