2022-03-09 18:37:04 +00:00
|
|
|
import { Injectable } from '@nestjs/common';
|
|
|
|
import * as crypto from 'crypto';
|
|
|
|
import { v4 } from 'uuid';
|
|
|
|
|
|
|
|
const IV_LENGTH = 16;
|
|
|
|
const ALGORITHM = 'aes-256-cbc';
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
export class TokenService {
|
|
|
|
public generateString(length: number): string {
|
|
|
|
return crypto.randomBytes(length).toString('hex').slice(0, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
public createUUID(): string {
|
|
|
|
return v4();
|
|
|
|
}
|
|
|
|
|
2022-03-09 20:03:29 +00:00
|
|
|
// https://stackoverflow.com/q/52212430
|
2022-03-09 18:37:04 +00:00
|
|
|
/**
|
|
|
|
* Symmetric encryption function
|
|
|
|
* @param text String to encrypt
|
|
|
|
* @param key Encryption key
|
|
|
|
* @returns Encrypted text
|
|
|
|
*/
|
|
|
|
public encrypt(text: string, key: string): string {
|
|
|
|
const iv = crypto.randomBytes(IV_LENGTH);
|
|
|
|
const cipher = crypto.createCipheriv(
|
|
|
|
ALGORITHM,
|
|
|
|
Buffer.from(key, 'hex'),
|
|
|
|
iv,
|
|
|
|
);
|
|
|
|
let encrypted = cipher.update(text);
|
|
|
|
encrypted = Buffer.concat([encrypted, cipher.final()]);
|
|
|
|
return `${iv.toString('hex')}:${encrypted.toString('hex')}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Symmetric decryption function
|
|
|
|
* @param text Encrypted string
|
|
|
|
* @param key Decryption key
|
|
|
|
* @returns Decrypted text
|
|
|
|
*/
|
|
|
|
public decrypt(text: string, key: string): string {
|
|
|
|
const [iv, encryptedText] = text
|
|
|
|
.split(':')
|
|
|
|
.map((part) => Buffer.from(part, 'hex'));
|
|
|
|
|
|
|
|
const decipher = crypto.createDecipheriv(
|
|
|
|
ALGORITHM,
|
|
|
|
Buffer.from(key, 'hex'),
|
|
|
|
iv,
|
|
|
|
);
|
|
|
|
|
|
|
|
let decrypted = decipher.update(encryptedText);
|
|
|
|
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
|
|
return decrypted.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public async encryptChallenge(
|
|
|
|
challenge: Record<string, any>,
|
|
|
|
): Promise<string> {
|
|
|
|
return this.encrypt(
|
|
|
|
JSON.stringify(challenge),
|
|
|
|
process.env.CHALLENGE_SECRET,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async decryptChallenge(
|
|
|
|
challenge: string,
|
|
|
|
): Promise<Record<string, any>> {
|
|
|
|
return JSON.parse(this.decrypt(challenge, process.env.CHALLENGE_SECRET));
|
|
|
|
}
|
|
|
|
}
|