refactor: prefer buffer (#26469)

* refactor: prefer buffer

* Update server/src/schema/tables/session.table.ts

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>

---------

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
This commit is contained in:
Jason Rasmussen
2026-02-24 08:26:36 -05:00
committed by GitHub
parent 4b8f90aa55
commit f07e2b58f0
16 changed files with 44 additions and 29 deletions
+2 -2
View File
@@ -24,7 +24,7 @@ describe(ApiKeyService.name, () => {
await sut.create(auth, { name: apiKey.name, permissions: apiKey.permissions });
expect(mocks.apiKey.create).toHaveBeenCalledWith({
key: 'super-secret (hashed)',
key: Buffer.from('super-secret (hashed)'),
name: apiKey.name,
permissions: apiKey.permissions,
userId: apiKey.userId,
@@ -44,7 +44,7 @@ describe(ApiKeyService.name, () => {
await sut.create(auth, { permissions: [Permission.All] });
expect(mocks.apiKey.create).toHaveBeenCalledWith({
key: 'super-secret (hashed)',
key: Buffer.from('super-secret (hashed)'),
name: 'API Key',
permissions: [Permission.All],
userId: auth.user.id,
+2 -2
View File
@@ -10,14 +10,14 @@ import { isGranted } from 'src/utils/access';
export class ApiKeyService extends BaseService {
async create(auth: AuthDto, dto: APIKeyCreateDto): Promise<APIKeyCreateResponseDto> {
const token = this.cryptoRepository.randomBytesAsText(32);
const tokenHashed = this.cryptoRepository.hashSha256(token);
const hashed = this.cryptoRepository.hashSha256(token);
if (auth.apiKey && !isGranted({ requested: dto.permissions, current: auth.apiKey.permissions })) {
throw new BadRequestException('Cannot grant permissions you do not have');
}
const entity = await this.apiKeyRepository.create({
key: tokenHashed,
key: hashed,
name: dto.name || 'API Key',
userId: auth.user.id,
permissions: dto.permissions,
+2 -2
View File
@@ -513,7 +513,7 @@ describe(AuthService.name, () => {
metadata: { adminRoute: false, sharedLinkRoute: false, uri: 'test' },
}),
).rejects.toBeInstanceOf(UnauthorizedException);
expect(mocks.apiKey.getKey).toHaveBeenCalledWith('auth_token (hashed)');
expect(mocks.apiKey.getKey).toHaveBeenCalledWith(Buffer.from('auth_token (hashed)'));
});
it('should throw an error if api key has insufficient permissions', async () => {
@@ -574,7 +574,7 @@ describe(AuthService.name, () => {
metadata: { adminRoute: false, sharedLinkRoute: false, uri: 'test' },
}),
).resolves.toEqual({ user: authUser, apiKey: expect.objectContaining(authApiKey) });
expect(mocks.apiKey.getKey).toHaveBeenCalledWith('auth_token (hashed)');
expect(mocks.apiKey.getKey).toHaveBeenCalledWith(Buffer.from('auth_token (hashed)'));
});
});
+7 -7
View File
@@ -456,8 +456,8 @@ export class AuthService extends BaseService {
}
private async validateApiKey(key: string): Promise<AuthDto> {
const hashedKey = this.cryptoRepository.hashSha256(key);
const apiKey = await this.apiKeyRepository.getKey(hashedKey);
const hashed = this.cryptoRepository.hashSha256(key);
const apiKey = await this.apiKeyRepository.getKey(hashed);
if (apiKey?.user) {
return {
user: apiKey.user,
@@ -476,9 +476,9 @@ export class AuthService extends BaseService {
return this.cryptoRepository.compareBcrypt(inputSecret, existingHash);
}
private async validateSession(tokenValue: string, headers: IncomingHttpHeaders): Promise<AuthDto> {
const hashedToken = this.cryptoRepository.hashSha256(tokenValue);
const session = await this.sessionRepository.getByToken(hashedToken);
private async validateSession(token: string, headers: IncomingHttpHeaders): Promise<AuthDto> {
const hashed = this.cryptoRepository.hashSha256(token);
const session = await this.sessionRepository.getByToken(hashed);
if (session?.user) {
const { appVersion, deviceOS, deviceType } = getUserAgentDetails(headers);
const now = DateTime.now();
@@ -543,10 +543,10 @@ export class AuthService extends BaseService {
private async createLoginResponse(user: UserAdmin, loginDetails: LoginDetails) {
const token = this.cryptoRepository.randomBytesAsText(32);
const tokenHashed = this.cryptoRepository.hashSha256(token);
const hashed = this.cryptoRepository.hashSha256(token);
await this.sessionRepository.create({
token: tokenHashed,
token: hashed,
deviceOS: loginDetails.deviceOS,
deviceType: loginDetails.deviceType,
appVersion: loginDetails.appVersion,
+2 -2
View File
@@ -33,14 +33,14 @@ export class SessionService extends BaseService {
}
const token = this.cryptoRepository.randomBytesAsText(32);
const tokenHashed = this.cryptoRepository.hashSha256(token);
const hashed = this.cryptoRepository.hashSha256(token);
const session = await this.sessionRepository.create({
parentId: auth.session.id,
userId: auth.user.id,
expiresAt: dto.duration ? DateTime.now().plus({ seconds: dto.duration }).toJSDate() : null,
deviceType: dto.deviceType,
deviceOS: dto.deviceOS,
token: tokenHashed,
token: hashed,
});
return { ...mapSession(session), token };
@@ -69,8 +69,9 @@ describe(SharedLinkService.name, () => {
it('should accept a valid shared link auth token', async () => {
mocks.sharedLink.get.mockResolvedValue({ ...sharedLinkStub.individual, password: '123' });
mocks.crypto.hashSha256.mockReturnValue('hashed-auth-token');
await expect(sut.getMine(authStub.adminSharedLink, ['hashed-auth-token'])).resolves.toBeDefined();
const secret = Buffer.from('auth-token-123');
mocks.crypto.hashSha256.mockReturnValue(secret);
await expect(sut.getMine(authStub.adminSharedLink, [secret.toString('base64')])).resolves.toBeDefined();
expect(mocks.sharedLink.get).toHaveBeenCalledWith(
authStub.adminSharedLink.user.id,
authStub.adminSharedLink.sharedLink?.id,
+1 -1
View File
@@ -236,6 +236,6 @@ export class SharedLinkService extends BaseService {
}
private asToken(sharedLink: { id: string; password: string }) {
return this.cryptoRepository.hashSha256(`${sharedLink.id}-${sharedLink.password}`);
return this.cryptoRepository.hashSha256(`${sharedLink.id}-${sharedLink.password}`).toString('base64');
}
}