xpeditis2.0/apps/backend/src/application/services/invitation.security.spec.ts
2026-09-14 11:19:29 +02:00

58 lines
2.5 KiB
TypeScript

import { Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InvitationService } from './invitation.service';
import { SubscriptionService } from './subscription.service';
import { InvitationToken } from '@domain/entities/invitation-token.entity';
import { UserRole } from '@domain/entities/user.entity';
import { InvitationTokenRepository } from '@domain/ports/out/invitation-token.repository';
import { UserRepository } from '@domain/ports/out/user.repository';
import { OrganizationRepository } from '@domain/ports/out/organization.repository';
import { EmailPort } from '@domain/ports/out/email.port';
describe('invitation secret handling', () => {
it('keeps the token in the email but out of success and failure logs', async () => {
const log = jest.spyOn(Logger.prototype, 'log').mockImplementation(() => undefined);
const error = jest.spyOn(Logger.prototype, 'error').mockImplementation(() => undefined);
try {
const invitation = InvitationToken.create({
id: 'invite-id',
token: 'test-only-invitation-secret',
email: 'user@example.org',
firstName: 'Test',
lastName: 'User',
role: UserRole.USER,
organizationId: 'org',
invitedById: 'admin',
expiresAt: new Date(Date.now() + 60_000),
});
const send = jest.fn().mockResolvedValue(undefined);
const service = new InvitationService(
{
findByToken: async () => invitation,
update: async () => invitation,
} as unknown as InvitationTokenRepository,
{
findById: async () => ({ firstName: 'Test', lastName: 'Admin' }),
} as unknown as UserRepository,
{ findById: async () => ({ name: 'Company' }) } as unknown as OrganizationRepository,
{ sendInvitationWithToken: send } as unknown as EmailPort,
new ConfigService({ FRONTEND_URL: 'https://example.org' }),
{} as SubscriptionService
);
await service['sendInvitationEmail'](invitation);
expect(send.mock.calls[0][5]).toBe(
'https://example.org/register?token=test-only-invitation-secret'
);
send.mockRejectedValue(new Error('test-only-invitation-secret'));
await expect(service['sendInvitationEmail'](invitation)).rejects.toThrow();
await service.markInvitationAsUsed(invitation.token);
expect(JSON.stringify([...log.mock.calls, ...error.mock.calls])).not.toContain(
invitation.token
);
} finally {
log.mockRestore();
error.mockRestore();
}
});
});