From 74f1198cf315a0293f33d1e8851a84f9b7a982ba Mon Sep 17 00:00:00 2001 From: "Juan Picado @jotadeveloper" Date: Sun, 3 Jun 2018 08:51:18 +0200 Subject: [PATCH] refactor: json web token relocated --- src/lib/auth.js | 29 +++++++++++++---------------- src/lib/crypto-utils.js | 13 +++++++++++++ types/index.js | 9 +++++++++ 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/lib/auth.js b/src/lib/auth.js index a9e06fcfc..ce0f18652 100644 --- a/src/lib/auth.js +++ b/src/lib/auth.js @@ -1,13 +1,13 @@ // @flow import {loadPlugin} from '../lib/plugin-loader'; -import jwt from 'jsonwebtoken'; import {ErrorCode} from './utils'; +import {aesDecrypt, aesEncrypt, signPayload, verifyPayload} from './crypto-utils'; import type {Config, Logger, Callback} from '@verdaccio/types'; import type {$Response, NextFunction} from 'express'; -import type {$RequestExtend} from '../../types'; -import {aesDecrypt, aesEncrypt} from './crypto-utils'; +import type {$RequestExtend, JWTPayload} from '../../types'; + const LoggerApi = require('./logger'); /** @@ -18,6 +18,7 @@ class Auth { logger: Logger; secret: string; plugins: Array; + static DEFAULT_EXPIRE_WEB_TOKEN: string = '7d'; constructor(config: Config) { this.config = config; @@ -300,18 +301,14 @@ class Auth { }; } - issueUIjwt(user: any, expire_time: string) { - return jwt.sign( - { - user: user.name, - group: user.real_groups && user.real_groups.length ? user.real_groups : undefined, - }, - this.secret, - { - notBefore: '1000', // Make sure the time will not rollback :) - expiresIn: expire_time || '7d', - } - ); + issueUIjwt(user: any, expiresIn: string) { + const {name, real_groups} = user; + const payload: JWTPayload = { + user: name, + group: real_groups && real_groups.length ? real_groups : undefined, + }; + + return signPayload(payload, this.secret, {expiresIn: expiresIn || Auth.DEFAULT_EXPIRE_WEB_TOKEN}); } /** @@ -322,7 +319,7 @@ class Auth { decode_token(token: string) { let decoded; try { - decoded = jwt.verify(token, this.secret); + decoded = verifyPayload(token, this.secret); } catch (err) { throw ErrorCode.getCode(401, err.message); } diff --git a/src/lib/crypto-utils.js b/src/lib/crypto-utils.js index 1ec3e73b1..8c4c376ad 100644 --- a/src/lib/crypto-utils.js +++ b/src/lib/crypto-utils.js @@ -1,6 +1,8 @@ // @flow import {createDecipher, createCipher, createHash, pseudoRandomBytes} from 'crypto'; +import jwt from 'jsonwebtoken'; +import type {JWTPayload, JWTSignOptions} from '../../types'; export const defaultAlgorithm = 'aes192'; @@ -41,3 +43,14 @@ export function stringToMD5(data: Buffer | string) { export function generateRandomHexString(length: number = 8) { return pseudoRandomBytes(length).toString('hex'); } + +export function signPayload(payload: JWTPayload, secret: string, options: JWTSignOptions) { + return jwt.sign(payload, secret, { + notBefore: '1000', // Make sure the time will not rollback :) + ...options, + }); +} + +export function verifyPayload(token: string, secret: string) { + return jwt.verify(token, secret); +} diff --git a/types/index.js b/types/index.js index ef5ef7ac8..091088430 100644 --- a/types/index.js +++ b/types/index.js @@ -113,6 +113,15 @@ export interface IStorage { getSecret(config: Config): Promise; } +export type JWTPayload = { + user: string; + group: string | void; +} + +export type JWTSignOptions = { + expiresIn: string; +} + export type $RequestExtend = $Request & {remote_user?: any} export type $ResponseExtend = $Response & {cookies?: any} export type $NextFunctionVer = NextFunction & mixed;