fix(core): Initialize JWT Secret before it's used anywhere (#7707)

HELP-394
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-11-15 12:17:18 +01:00
committed by GitHub
parent 5aee2b768f
commit 3460eb5eeb
7 changed files with 75 additions and 53 deletions

View File

@@ -1,17 +1,34 @@
import { Service } from 'typedi';
import * as jwt from 'jsonwebtoken';
import { createHash } from 'crypto';
import jwt from 'jsonwebtoken';
import { InstanceSettings } from 'n8n-core';
import config from '@/config';
@Service()
export class JwtService {
private readonly userManagementSecret = config.getEnv('userManagement.jwtSecret');
readonly jwtSecret = config.getEnv('userManagement.jwtSecret');
public signData(payload: object, options: jwt.SignOptions = {}): string {
return jwt.sign(payload, this.userManagementSecret, options);
constructor({ encryptionKey }: InstanceSettings) {
this.jwtSecret = config.getEnv('userManagement.jwtSecret');
if (!this.jwtSecret) {
// If we don't have a JWT secret set, generate one based on encryption key.
// For a key off every other letter from encryption key
// CAREFUL: do not change this or it breaks all existing tokens.
let baseKey = '';
for (let i = 0; i < encryptionKey.length; i += 2) {
baseKey += encryptionKey[i];
}
this.jwtSecret = createHash('sha256').update(baseKey).digest('hex');
config.set('userManagement.jwtSecret', this.jwtSecret);
}
}
public verifyToken<T = JwtPayload>(token: string, options: jwt.VerifyOptions = {}) {
return jwt.verify(token, this.userManagementSecret, options) as T;
public sign(payload: object, options: jwt.SignOptions = {}): string {
return jwt.sign(payload, this.jwtSecret, options);
}
public verify<T = JwtPayload>(token: string, options: jwt.VerifyOptions = {}) {
return jwt.verify(token, this.jwtSecret, options) as T;
}
}

View File

@@ -63,7 +63,7 @@ export class UserService {
}
generatePasswordResetToken(user: User, expiresIn = '20m') {
return this.jwtService.signData(
return this.jwtService.sign(
{ sub: user.id, passwordSha: createPasswordSha(user) },
{ expiresIn },
);
@@ -82,7 +82,7 @@ export class UserService {
async resolvePasswordResetToken(token: string): Promise<User | undefined> {
let decodedToken: JwtPayload & { passwordSha: string };
try {
decodedToken = this.jwtService.verifyToken(token);
decodedToken = this.jwtService.verify(token);
} catch (e) {
if (e instanceof TokenExpiredError) {
this.logger.debug('Reset password token expired', { token });