fix(api): sync stripe customer email on change (#3243)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-06 21:38:25 +02:00
1 parent 6e28092cdc
commit cc5545c333
17 files changed
+509 -125

No files matched your search

@@ -12,6 +12,7 @@ import type {EntityAssetService, PreparedAssetUpload} from '@app/api/infrastruct
import {Logger} from '@app/api/Logger';
import {getInstanceConfigRepository} from '@app/api/middleware/ServiceSingletons';
import type {User} from '@app/api/models/User';
import {enqueueStripeCustomerEmailSync} from '@app/api/stripe/StripeCustomer';
import {assertNoDiscriminatorChange, reserveUsername, type UsernameReservation} from '@app/api/user/UniqueUsernames';
import {USERNAME_MODE_DISCRIMINATOR} from '@app/api/user/UserTag';
import {TagAlreadyTakenError} from '@fluxer/errors/src/domains/user/TagAlreadyTakenError';
@@ -218,6 +219,7 @@ export class AdminUserProfileService {
users: userRepository,
cache: cacheService,
contactChangeLog: contactChangeLogService,
worker: workerService,
} = this.deps.apiContext.services;
const {auditService, updatePropagator} = this.deps;
const userId = createUserID(data.user_id);
@@ -240,6 +242,7 @@ export class AdminUserProfileService {
reason: 'admin_action',
actorUserId: adminUserId,
});
await enqueueStripeCustomerEmailSync(workerService, user, updatedUser);
await auditService.createAuditLog({
adminUserId,
targetType: 'user',
@@ -2,11 +2,12 @@
import {createTestAccount, setUserACLs} from '@app/api/auth/tests/AuthTestUtils';
import {type ApiTestHarness, createApiTestHarness} from '@app/api/test/ApiTestHarness';
import {NoopWorkerService} from '@app/api/test/NoopWorkerService';
import {HTTP_STATUS, TEST_CREDENTIALS} from '@app/api/test/TestConstants';
import {createBuilder, createBuilderWithoutAuth} from '@app/api/test/TestRequestBuilder';
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
import {UserFlags} from '@fluxer/constants/src/UserConstants';
import {afterAll, beforeAll, beforeEach, describe, expect, test} from 'vitest';
import {afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi} from 'vitest';
interface ChangeLogResponse {
entries: Array<{
@@ -44,6 +45,9 @@ describe('Admin User Change Log and Flags', () => {
beforeEach(async () => {
await harness.reset();
});
afterEach(() => {
vi.restoreAllMocks();
});
afterAll(async () => {
await harness?.shutdown();
});
@@ -176,6 +180,37 @@ describe('Admin User Change Log and Flags', () => {
.execute();
});
});
describe('PATCH /admin/users/{user_id}/email', () => {
test('queues a Stripe customer email sync for users with a Stripe customer', async () => {
const admin = await createTestAccount(harness);
await setUserACLs(harness, admin, [AdminACLs.AUTHENTICATE, AdminACLs.WILDCARD]);
const target = await createTestAccount(harness);
await createBuilderWithoutAuth(harness)
.post(`/test/users/${target.userId}/premium`)
.body({stripe_customer_id: 'cus_admin_email_sync'})
.expect(HTTP_STATUS.OK)
.execute();
const addJob = vi.spyOn(NoopWorkerService.prototype, 'addJob');
await createBuilder(harness, `${admin.token}`)
.patch(`/admin/users/${target.userId}/email`)
.body({email: `admin-changed-${Date.now()}@example.com`})
.expect(HTTP_STATUS.OK)
.execute();
expect(addJob).toHaveBeenCalledWith('syncStripeCustomerEmail', {userId: target.userId});
});
test('does not queue a Stripe customer email sync for users without a Stripe customer', async () => {
const admin = await createTestAccount(harness);
await setUserACLs(harness, admin, [AdminACLs.AUTHENTICATE, AdminACLs.WILDCARD]);
const target = await createTestAccount(harness);
const addJob = vi.spyOn(NoopWorkerService.prototype, 'addJob');
await createBuilder(harness, `${admin.token}`)
.patch(`/admin/users/${target.userId}/email`)
.body({email: `admin-changed-${Date.now()}@example.com`})
.expect(HTTP_STATUS.OK)
.execute();
expect(addJob).not.toHaveBeenCalledWith('syncStripeCustomerEmail', expect.anything());
});
});
describe('PUT /admin/users/{user_id}/email-verification', () => {
test('verifying email clears email_bounced', async () => {
const admin = await createTestAccount(harness);