fix: improper filename sanitizing (#32028)

fix: improper filename sanitizing (#32009)

(cherry picked from commit f652f55ffda784e87c8f681f797f4b2cb708d96b)

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
This commit is contained in:
immich-push-o-matic[bot]
2026-10-02 16:02:39 +00:00
committed by GitHub
co-authored by Daniel Dietzler
parent 6e5a4fdf00
commit 6fbb4d9642
4 changed files with 29 additions and 3 deletions
+26
View File
@@ -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 });
+1 -1
View File
@@ -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<UserAdmin> {
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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');