icynet-auth-server/src/modules/utility/services/token.service.ts

74 lines
1.8 KiB
TypeScript

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();
}
// https://stackoverflow.com/q/52212430
/**
* 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));
}
}