From 3cc2d61b32bb5edc258a4adb3a603c4282f35f7a Mon Sep 17 00:00:00 2001 From: br4yd Date: Wed, 5 Aug 2026 11:02:25 +0200 Subject: [PATCH] fix(server): force full sync on either public users transition Re-enabling public users left previously hidden users stuck missing from non-admin candidate lists, for the same reason as the disable direction: incremental sync never re-fetches already-acked rows. --- server/src/services/sync.service.ts | 2 +- .../medium/specs/services/sync.service.spec.ts | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/server/src/services/sync.service.ts b/server/src/services/sync.service.ts index 7dc111de5b..ef2dcd792a 100644 --- a/server/src/services/sync.service.ts +++ b/server/src/services/sync.service.ts @@ -89,7 +89,7 @@ const throwSessionRequired = () => { export class SyncService extends BaseService { @OnEvent({ name: 'ConfigUpdate', workers: [ImmichWorker.Api] }) async onConfigUpdate({ newConfig, oldConfig }: ArgOf<'ConfigUpdate'>) { - if (oldConfig.server.publicUsers && !newConfig.server.publicUsers) { + if (oldConfig.server.publicUsers !== newConfig.server.publicUsers) { await this.sessionRepository.requireFullSyncForNonAdmins(); } } diff --git a/server/test/medium/specs/services/sync.service.spec.ts b/server/test/medium/specs/services/sync.service.spec.ts index 496b5a95af..76108e7448 100644 --- a/server/test/medium/specs/services/sync.service.spec.ts +++ b/server/test/medium/specs/services/sync.service.spec.ts @@ -275,14 +275,14 @@ describe(SyncService.name, () => { await expect(isPendingSyncReset(ctx.database, session.id)).resolves.toBe(false); }); - it('should not require a full sync when public users is enabled', async () => { + it('should require a full sync for non-admins when public users is enabled', async () => { const { sut, ctx } = setup(await getKyselyDB()); const { user } = await ctx.newUser(); const { session } = await ctx.newSession({ userId: user.id }); await sut.onConfigUpdate({ oldConfig: withPublicUsers(false), newConfig: withPublicUsers(true) }); - await expect(isPendingSyncReset(ctx.database, session.id)).resolves.toBe(false); + await expect(isPendingSyncReset(ctx.database, session.id)).resolves.toBe(true); }); it('should not require a full sync when public users was already disabled', async () => { @@ -294,5 +294,15 @@ describe(SyncService.name, () => { await expect(isPendingSyncReset(ctx.database, session.id)).resolves.toBe(false); }); + + it('should not require a full sync when public users was already enabled', async () => { + const { sut, ctx } = setup(await getKyselyDB()); + const { user } = await ctx.newUser(); + const { session } = await ctx.newSession({ userId: user.id }); + + await sut.onConfigUpdate({ oldConfig: withPublicUsers(true), newConfig: withPublicUsers(true) }); + + await expect(isPendingSyncReset(ctx.database, session.id)).resolves.toBe(false); + }); }); });