mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
1.6 KiB
63 lines
1.6 KiB
import { getRandomString } from '@ghostfolio/api/helper/string.helper';
|
|
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
|
|
import { ApiKeyResponse } from '@ghostfolio/common/interfaces';
|
|
|
|
import { Injectable } from '@nestjs/common';
|
|
import { pbkdf2Sync } from 'node:crypto';
|
|
|
|
@Injectable()
|
|
export class ApiKeyService {
|
|
private readonly algorithm = 'sha256';
|
|
private readonly iterations = 100000;
|
|
private readonly keyLength = 64;
|
|
|
|
public constructor(private readonly prismaService: PrismaService) {}
|
|
|
|
public async create({ userId }: { userId: string }): Promise<ApiKeyResponse> {
|
|
const apiKey = this.generateApiKey();
|
|
const hashedKey = this.hashApiKey(apiKey);
|
|
|
|
await this.prismaService.apiKey.deleteMany({ where: { userId } });
|
|
|
|
await this.prismaService.apiKey.create({
|
|
data: {
|
|
hashedKey,
|
|
userId
|
|
}
|
|
});
|
|
|
|
return { apiKey };
|
|
}
|
|
|
|
public async getUserByApiKey(apiKey: string) {
|
|
const hashedKey = this.hashApiKey(apiKey);
|
|
|
|
const { user } = await this.prismaService.apiKey.findUnique({
|
|
include: { user: true },
|
|
where: { hashedKey }
|
|
});
|
|
|
|
return user;
|
|
}
|
|
|
|
public hashApiKey(apiKey: string): string {
|
|
return pbkdf2Sync(
|
|
apiKey,
|
|
'',
|
|
this.iterations,
|
|
this.keyLength,
|
|
this.algorithm
|
|
).toString('hex');
|
|
}
|
|
|
|
private generateApiKey(): string {
|
|
return getRandomString(32)
|
|
.split('')
|
|
.reduce((acc, char, index) => {
|
|
const chunkIndex = Math.floor(index / 4);
|
|
acc[chunkIndex] = (acc[chunkIndex] || '') + char;
|
|
return acc;
|
|
}, [])
|
|
.join('-');
|
|
}
|
|
}
|
|
|