mirror of
https://github.com/immich-app/immich.git
synced 2025-11-01 14:37:41 +09:00
fix(web): OAuth quota size (#18526)
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Docker / pre-job (push) Waiting to run
Docker / Re-Tag ML () (push) Blocked by required conditions
Docker / Re-Tag ML (-armnn) (push) Blocked by required conditions
Docker / Re-Tag ML (-cuda) (push) Blocked by required conditions
Docker / Re-Tag ML (-openvino) (push) Blocked by required conditions
Docker / Re-Tag ML (-rknn) (push) Blocked by required conditions
Docker / Re-Tag ML (-rocm) (push) Blocked by required conditions
Docker / Re-Tag Server () (push) Blocked by required conditions
Docker / Build and Push ML (armnn, linux/arm64, -armnn) (push) Blocked by required conditions
Docker / Build and Push ML (cpu, ) (push) Blocked by required conditions
Docker / Build and Push ML (cuda, linux/amd64, -cuda) (push) Blocked by required conditions
Docker / Build and Push ML (openvino, linux/amd64, -openvino) (push) Blocked by required conditions
Docker / Build and Push ML (rknn, linux/arm64, -rknn) (push) Blocked by required conditions
Docker / Build and Push ML (rocm, linux/amd64, {"linux/amd64": "mich"}, -rocm) (push) Blocked by required conditions
Docker / Build and Push Server (push) Blocked by required conditions
Docker / Docker Build & Push Server Success (push) Blocked by required conditions
Docker / Docker Build & Push ML Success (push) Blocked by required conditions
Docs build / pre-job (push) Waiting to run
Docs build / Docs Build (push) Blocked by required conditions
Static Code Analysis / pre-job (push) Waiting to run
Static Code Analysis / Run Dart Code Analysis (push) Blocked by required conditions
Static Code Analysis / zizmor (push) Waiting to run
Test / pre-job (push) Waiting to run
Test / Test & Lint Server (push) Blocked by required conditions
Test / Unit Test CLI (push) Blocked by required conditions
Test / Unit Test CLI (Windows) (push) Blocked by required conditions
Test / Lint Web (push) Blocked by required conditions
Test / Test Web (push) Blocked by required conditions
Test / Test i18n (push) Blocked by required conditions
Test / End-to-End Lint (push) Blocked by required conditions
Test / Medium Tests (Server) (push) Blocked by required conditions
Test / End-to-End Tests (Server & CLI) (ubuntu-24.04-arm) (push) Blocked by required conditions
Test / End-to-End Tests (Server & CLI) (ubuntu-latest) (push) Blocked by required conditions
Test / End-to-End Tests (Web) (ubuntu-24.04-arm) (push) Blocked by required conditions
Test / End-to-End Tests (Web) (ubuntu-latest) (push) Blocked by required conditions
Test / End-to-End Tests Success (push) Blocked by required conditions
Test / Unit Test Mobile (push) Blocked by required conditions
Test / Unit Test ML (push) Blocked by required conditions
Test / .github Files Formatting (push) Blocked by required conditions
Test / ShellCheck (push) Waiting to run
Test / OpenAPI Clients (push) Waiting to run
Test / SQL Schema Checks (push) Waiting to run
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Docker / pre-job (push) Waiting to run
Docker / Re-Tag ML () (push) Blocked by required conditions
Docker / Re-Tag ML (-armnn) (push) Blocked by required conditions
Docker / Re-Tag ML (-cuda) (push) Blocked by required conditions
Docker / Re-Tag ML (-openvino) (push) Blocked by required conditions
Docker / Re-Tag ML (-rknn) (push) Blocked by required conditions
Docker / Re-Tag ML (-rocm) (push) Blocked by required conditions
Docker / Re-Tag Server () (push) Blocked by required conditions
Docker / Build and Push ML (armnn, linux/arm64, -armnn) (push) Blocked by required conditions
Docker / Build and Push ML (cpu, ) (push) Blocked by required conditions
Docker / Build and Push ML (cuda, linux/amd64, -cuda) (push) Blocked by required conditions
Docker / Build and Push ML (openvino, linux/amd64, -openvino) (push) Blocked by required conditions
Docker / Build and Push ML (rknn, linux/arm64, -rknn) (push) Blocked by required conditions
Docker / Build and Push ML (rocm, linux/amd64, {"linux/amd64": "mich"}, -rocm) (push) Blocked by required conditions
Docker / Build and Push Server (push) Blocked by required conditions
Docker / Docker Build & Push Server Success (push) Blocked by required conditions
Docker / Docker Build & Push ML Success (push) Blocked by required conditions
Docs build / pre-job (push) Waiting to run
Docs build / Docs Build (push) Blocked by required conditions
Static Code Analysis / pre-job (push) Waiting to run
Static Code Analysis / Run Dart Code Analysis (push) Blocked by required conditions
Static Code Analysis / zizmor (push) Waiting to run
Test / pre-job (push) Waiting to run
Test / Test & Lint Server (push) Blocked by required conditions
Test / Unit Test CLI (push) Blocked by required conditions
Test / Unit Test CLI (Windows) (push) Blocked by required conditions
Test / Lint Web (push) Blocked by required conditions
Test / Test Web (push) Blocked by required conditions
Test / Test i18n (push) Blocked by required conditions
Test / End-to-End Lint (push) Blocked by required conditions
Test / Medium Tests (Server) (push) Blocked by required conditions
Test / End-to-End Tests (Server & CLI) (ubuntu-24.04-arm) (push) Blocked by required conditions
Test / End-to-End Tests (Server & CLI) (ubuntu-latest) (push) Blocked by required conditions
Test / End-to-End Tests (Web) (ubuntu-24.04-arm) (push) Blocked by required conditions
Test / End-to-End Tests (Web) (ubuntu-latest) (push) Blocked by required conditions
Test / End-to-End Tests Success (push) Blocked by required conditions
Test / Unit Test Mobile (push) Blocked by required conditions
Test / Unit Test ML (push) Blocked by required conditions
Test / .github Files Formatting (push) Blocked by required conditions
Test / ShellCheck (push) Waiting to run
Test / OpenAPI Clients (push) Waiting to run
Test / SQL Schema Checks (push) Waiting to run
fix(server): oauth quota size
This commit is contained in:
@@ -123,7 +123,7 @@ The default configuration looks like this:
|
|||||||
"buttonText": "Login with OAuth",
|
"buttonText": "Login with OAuth",
|
||||||
"clientId": "",
|
"clientId": "",
|
||||||
"clientSecret": "",
|
"clientSecret": "",
|
||||||
"defaultStorageQuota": 0,
|
"defaultStorageQuota": null,
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"issuerUrl": "",
|
"issuerUrl": "",
|
||||||
"mobileOverrideEnabled": false,
|
"mobileOverrideEnabled": false,
|
||||||
|
|||||||
@@ -204,7 +204,7 @@
|
|||||||
"oauth_storage_quota_claim": "Storage quota claim",
|
"oauth_storage_quota_claim": "Storage quota claim",
|
||||||
"oauth_storage_quota_claim_description": "Automatically set the user's storage quota to the value of this claim.",
|
"oauth_storage_quota_claim_description": "Automatically set the user's storage quota to the value of this claim.",
|
||||||
"oauth_storage_quota_default": "Default storage quota (GiB)",
|
"oauth_storage_quota_default": "Default storage quota (GiB)",
|
||||||
"oauth_storage_quota_default_description": "Quota in GiB to be used when no claim is provided (Enter 0 for unlimited quota).",
|
"oauth_storage_quota_default_description": "Quota in GiB to be used when no claim is provided.",
|
||||||
"oauth_timeout": "Request Timeout",
|
"oauth_timeout": "Request Timeout",
|
||||||
"oauth_timeout_description": "Timeout for requests in milliseconds",
|
"oauth_timeout_description": "Timeout for requests in milliseconds",
|
||||||
"password_enable_description": "Login with email and password",
|
"password_enable_description": "Login with email and password",
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class SystemConfigOAuthDto {
|
|||||||
String clientSecret;
|
String clientSecret;
|
||||||
|
|
||||||
/// Minimum value: 0
|
/// Minimum value: 0
|
||||||
num defaultStorageQuota;
|
int? defaultStorageQuota;
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ class SystemConfigOAuthDto {
|
|||||||
(buttonText.hashCode) +
|
(buttonText.hashCode) +
|
||||||
(clientId.hashCode) +
|
(clientId.hashCode) +
|
||||||
(clientSecret.hashCode) +
|
(clientSecret.hashCode) +
|
||||||
(defaultStorageQuota.hashCode) +
|
(defaultStorageQuota == null ? 0 : defaultStorageQuota!.hashCode) +
|
||||||
(enabled.hashCode) +
|
(enabled.hashCode) +
|
||||||
(issuerUrl.hashCode) +
|
(issuerUrl.hashCode) +
|
||||||
(mobileOverrideEnabled.hashCode) +
|
(mobileOverrideEnabled.hashCode) +
|
||||||
@@ -119,7 +119,11 @@ class SystemConfigOAuthDto {
|
|||||||
json[r'buttonText'] = this.buttonText;
|
json[r'buttonText'] = this.buttonText;
|
||||||
json[r'clientId'] = this.clientId;
|
json[r'clientId'] = this.clientId;
|
||||||
json[r'clientSecret'] = this.clientSecret;
|
json[r'clientSecret'] = this.clientSecret;
|
||||||
|
if (this.defaultStorageQuota != null) {
|
||||||
json[r'defaultStorageQuota'] = this.defaultStorageQuota;
|
json[r'defaultStorageQuota'] = this.defaultStorageQuota;
|
||||||
|
} else {
|
||||||
|
// json[r'defaultStorageQuota'] = null;
|
||||||
|
}
|
||||||
json[r'enabled'] = this.enabled;
|
json[r'enabled'] = this.enabled;
|
||||||
json[r'issuerUrl'] = this.issuerUrl;
|
json[r'issuerUrl'] = this.issuerUrl;
|
||||||
json[r'mobileOverrideEnabled'] = this.mobileOverrideEnabled;
|
json[r'mobileOverrideEnabled'] = this.mobileOverrideEnabled;
|
||||||
@@ -148,7 +152,7 @@ class SystemConfigOAuthDto {
|
|||||||
buttonText: mapValueOfType<String>(json, r'buttonText')!,
|
buttonText: mapValueOfType<String>(json, r'buttonText')!,
|
||||||
clientId: mapValueOfType<String>(json, r'clientId')!,
|
clientId: mapValueOfType<String>(json, r'clientId')!,
|
||||||
clientSecret: mapValueOfType<String>(json, r'clientSecret')!,
|
clientSecret: mapValueOfType<String>(json, r'clientSecret')!,
|
||||||
defaultStorageQuota: num.parse('${json[r'defaultStorageQuota']}'),
|
defaultStorageQuota: mapValueOfType<int>(json, r'defaultStorageQuota'),
|
||||||
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
enabled: mapValueOfType<bool>(json, r'enabled')!,
|
||||||
issuerUrl: mapValueOfType<String>(json, r'issuerUrl')!,
|
issuerUrl: mapValueOfType<String>(json, r'issuerUrl')!,
|
||||||
mobileOverrideEnabled: mapValueOfType<bool>(json, r'mobileOverrideEnabled')!,
|
mobileOverrideEnabled: mapValueOfType<bool>(json, r'mobileOverrideEnabled')!,
|
||||||
|
|||||||
@@ -14344,8 +14344,10 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"defaultStorageQuota": {
|
"defaultStorageQuota": {
|
||||||
|
"format": "int64",
|
||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"type": "number"
|
"nullable": true,
|
||||||
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
|||||||
@@ -1392,7 +1392,7 @@ export type SystemConfigOAuthDto = {
|
|||||||
buttonText: string;
|
buttonText: string;
|
||||||
clientId: string;
|
clientId: string;
|
||||||
clientSecret: string;
|
clientSecret: string;
|
||||||
defaultStorageQuota: number;
|
defaultStorageQuota: number | null;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
issuerUrl: string;
|
issuerUrl: string;
|
||||||
mobileOverrideEnabled: boolean;
|
mobileOverrideEnabled: boolean;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export interface SystemConfig {
|
|||||||
buttonText: string;
|
buttonText: string;
|
||||||
clientId: string;
|
clientId: string;
|
||||||
clientSecret: string;
|
clientSecret: string;
|
||||||
defaultStorageQuota: number;
|
defaultStorageQuota: number | null;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
issuerUrl: string;
|
issuerUrl: string;
|
||||||
mobileOverrideEnabled: boolean;
|
mobileOverrideEnabled: boolean;
|
||||||
@@ -253,7 +253,7 @@ export const defaults = Object.freeze<SystemConfig>({
|
|||||||
buttonText: 'Login with OAuth',
|
buttonText: 'Login with OAuth',
|
||||||
clientId: '',
|
clientId: '',
|
||||||
clientSecret: '',
|
clientSecret: '',
|
||||||
defaultStorageQuota: 0,
|
defaultStorageQuota: null,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
issuerUrl: '',
|
issuerUrl: '',
|
||||||
mobileOverrideEnabled: false,
|
mobileOverrideEnabled: false,
|
||||||
|
|||||||
@@ -360,7 +360,9 @@ class SystemConfigOAuthDto {
|
|||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@Min(0)
|
@Min(0)
|
||||||
defaultStorageQuota!: number;
|
@Optional({ nullable: true })
|
||||||
|
@ApiProperty({ type: 'integer', format: 'int64' })
|
||||||
|
defaultStorageQuota!: number | null;
|
||||||
|
|
||||||
@ValidateBoolean()
|
@ValidateBoolean()
|
||||||
enabled!: boolean;
|
enabled!: boolean;
|
||||||
|
|||||||
@@ -704,7 +704,7 @@ describe(AuthService.name, () => {
|
|||||||
expect(mocks.user.create).toHaveBeenCalledWith(expect.objectContaining({ quotaSizeInBytes: 1_073_741_824 }));
|
expect(mocks.user.create).toHaveBeenCalledWith(expect.objectContaining({ quotaSizeInBytes: 1_073_741_824 }));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not set quota for 0 quota', async () => {
|
it('should set quota for 0 quota', async () => {
|
||||||
const user = factory.userAdmin({ oauthId: 'oauth-id' });
|
const user = factory.userAdmin({ oauthId: 'oauth-id' });
|
||||||
|
|
||||||
mocks.systemMetadata.get.mockResolvedValue(systemConfigStub.oauthWithStorageQuota);
|
mocks.systemMetadata.get.mockResolvedValue(systemConfigStub.oauthWithStorageQuota);
|
||||||
@@ -726,7 +726,7 @@ describe(AuthService.name, () => {
|
|||||||
email: user.email,
|
email: user.email,
|
||||||
name: ' ',
|
name: ' ',
|
||||||
oauthId: user.oauthId,
|
oauthId: user.oauthId,
|
||||||
quotaSizeInBytes: null,
|
quotaSizeInBytes: 0,
|
||||||
storageLabel: null,
|
storageLabel: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ export class AuthService extends BaseService {
|
|||||||
name: userName,
|
name: userName,
|
||||||
email: profile.email,
|
email: profile.email,
|
||||||
oauthId: profile.sub,
|
oauthId: profile.sub,
|
||||||
quotaSizeInBytes: storageQuota * HumanReadableSize.GiB || null,
|
quotaSizeInBytes: storageQuota === null ? null : storageQuota * HumanReadableSize.GiB,
|
||||||
storageLabel: storageLabel || null,
|
storageLabel: storageLabel || null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ const updatedConfig = Object.freeze<SystemConfig>({
|
|||||||
buttonText: 'Login with OAuth',
|
buttonText: 'Login with OAuth',
|
||||||
clientId: '',
|
clientId: '',
|
||||||
clientSecret: '',
|
clientSecret: '',
|
||||||
defaultStorageQuota: 0,
|
defaultStorageQuota: null,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
issuerUrl: '',
|
issuerUrl: '',
|
||||||
mobileOverrideEnabled: false,
|
mobileOverrideEnabled: false,
|
||||||
|
|||||||
@@ -182,7 +182,7 @@
|
|||||||
label={$t('admin.oauth_storage_quota_default').toUpperCase()}
|
label={$t('admin.oauth_storage_quota_default').toUpperCase()}
|
||||||
description={$t('admin.oauth_storage_quota_default_description')}
|
description={$t('admin.oauth_storage_quota_default_description')}
|
||||||
bind:value={config.oauth.defaultStorageQuota}
|
bind:value={config.oauth.defaultStorageQuota}
|
||||||
required={true}
|
required={false}
|
||||||
disabled={disabled || !config.oauth.enabled}
|
disabled={disabled || !config.oauth.enabled}
|
||||||
isEdited={!(config.oauth.defaultStorageQuota == savedConfig.oauth.defaultStorageQuota)}
|
isEdited={!(config.oauth.defaultStorageQuota == savedConfig.oauth.defaultStorageQuota)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
inputType: SettingInputFieldType;
|
inputType: SettingInputFieldType;
|
||||||
value: string | number | undefined;
|
value: string | number | undefined | null;
|
||||||
min?: number;
|
min?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
step?: string;
|
step?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user