diff --git a/server/src/services/auth.service.spec.ts b/server/src/services/auth.service.spec.ts index 913620313..54428a5e8 100644 --- a/server/src/services/auth.service.spec.ts +++ b/server/src/services/auth.service.spec.ts @@ -1298,6 +1298,32 @@ describe(AuthService.name, () => { }); }); + it('should sync a storage label with dots on subsequent logins when a custom claim is configured', async () => { + const user = UserFactory.create({ oauthId: 'oauth-id', storageLabel: 'custom-label' }); + + mocks.systemMetadata.get.mockResolvedValue({ + oauth: { ...systemConfigStub.oauthWithAutoRegister.oauth, storageLabelClaim: 'immich_label' }, + }); + mocks.oauth.getProfileAndOAuthSid.mockResolvedValue({ + profile: OAuthProfileFactory.create({ sub: user.oauthId!, immich_label: 'synced.label' }), + }); + mocks.user.getByOAuthId.mockResolvedValue(user); + mocks.user.getByStorageLabel.mockResolvedValue(void 0); + mocks.user.update.mockResolvedValue({ ...user, storageLabel: 'synced-label' }); + mocks.session.create.mockResolvedValue(SessionFactory.create()); + + await sut.callback( + { url: 'http://immich/auth/login?code=abc123', state: 'xyz789', codeVerifier: 'foo' }, + {}, + loginDetails, + ); + + expect(mocks.user.update).toHaveBeenCalledWith(user.id, { + storageLabel: 'synced.label', + updatedAt: expect.any(Date), + }); + }); + it('should promote an existing user to admin if the role claim contains admin on login', async () => { const oauthId = 'oauth-id'; const user = UserFactory.create({ isAdmin: false, oauthId }); diff --git a/server/src/services/auth.service.ts b/server/src/services/auth.service.ts index 8d5da7b50..e5909e9a9 100644 --- a/server/src/services/auth.service.ts +++ b/server/src/services/auth.service.ts @@ -679,7 +679,7 @@ export class AuthService extends BaseService { return null; } - return sanitize(label.replaceAll('.', '')); + return sanitize(label); } private async syncOAuthClaims(user: UserAdmin, profile: OAuthProfile, oauth: OAuthClaimsConfig): Promise { diff --git a/server/src/services/base.service.ts b/server/src/services/base.service.ts index c15567d43..2ff5dcc40 100644 --- a/server/src/services/base.service.ts +++ b/server/src/services/base.service.ts @@ -338,7 +338,7 @@ export class BaseService { payload.password = await this.cryptoRepository.hashBcrypt(payload.password, SALT_ROUNDS); } if (payload.storageLabel) { - payload.storageLabel = sanitize(payload.storageLabel.replaceAll('.', '')); + payload.storageLabel = sanitize(payload.storageLabel); } const clusterGroup = await this.clusterGroupRepository.create(); diff --git a/server/src/validation.ts b/server/src/validation.ts index 519edadff..38a605211 100644 --- a/server/src/validation.ts +++ b/server/src/validation.ts @@ -247,6 +247,6 @@ export const hexColor = z .regex(hexColorRegex) .transform((val) => (val.startsWith('#') ? val : `#${val}`)); -export const sanitizeFilename = z.string().transform((val) => sanitize(val.replaceAll('.', ''))); +export const sanitizeFilename = z.string().transform((val) => sanitize(val)); export const uniqueIds = z.array(z.uuid()).refine((ids) => ids.length === new Set(ids).size, 'Items must be unique');