From 98b6451021e7aaf6e276d05d7f30885e81663f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 10 Jul 2026 10:08:45 +0200 Subject: [PATCH 1/3] Upgrade SDK --- bun.lock | 5 ++--- package.json | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bun.lock b/bun.lock index f438c612cb..d00be54bc2 100644 --- a/bun.lock +++ b/bun.lock @@ -1,12 +1,11 @@ { "lockfileVersion": 1, - "configVersion": 0, "workspaces": { "": { "name": "@appwrite/console", "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@4b3ae78", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@6be9e62", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bfe7ce3", "@appwrite.io/pink-legacy": "^1.0.3", @@ -126,7 +125,7 @@ "@analytics/type-utils": ["@analytics/type-utils@0.6.4", "", {}, "sha512-Ou1gQxFakOWLcPnbFVsrPb8g1wLLUZYYJXDPjHkG07+5mustGs5yqACx42UAu4A6NszNN6Z5gGxhyH45zPWRxw=="], - "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@4b3ae78", { "dependencies": { "json-bigint": "1.0.0" } }], + "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@6be9e62", { "dependencies": { "json-bigint": "1.0.0" } }], "@appwrite.io/pink-icons": ["@appwrite.io/pink-icons@0.25.0", "", {}, "sha512-0O3i2oEuh5mWvjO80i+X6rbzrWLJ1m5wmv2/M3a1p2PyBJsFxN8xQMTEmTn3Wl/D26SsM7SpzbdW6gmfgoVU9Q=="], diff --git a/package.json b/package.json index ae999bd918..85eaefc7ea 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@4b3ae78", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@6be9e62", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bfe7ce3", "@appwrite.io/pink-legacy": "^1.0.3", From 16bc0d102b917d0014dff3ad846587d34f27c45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 10 Jul 2026 10:30:14 +0200 Subject: [PATCH 2/3] Add Appwrite provider; Improve OIDC provider --- src/lib/stores/oauth-providers.ts | 6 ++ .../auth/(providers)/mainOAuth.svelte | 57 +++++++++++++++++-- .../auth/(providers)/oidcPromptPicker.svelte | 42 ++++++++++++++ .../auth/updateOAuth.ts | 23 ++++++-- 4 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcPromptPicker.svelte diff --git a/src/lib/stores/oauth-providers.ts b/src/lib/stores/oauth-providers.ts index f1b8d699dc..553e3a7ab4 100644 --- a/src/lib/stores/oauth-providers.ts +++ b/src/lib/stores/oauth-providers.ts @@ -23,6 +23,12 @@ export const oAuthProviders: Record = { docs: 'https://developer.apple.com/sign-in-with-apple/', component: Main }, + appwrite: { + name: 'Appwrite', + icon: 'appwrite', + docs: 'https://appwrite.io/docs/products/auth/oauth2', + component: Main + }, auth0: { name: 'Auth0', icon: 'auth0', diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/mainOAuth.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/mainOAuth.svelte index 7dd6181888..1b6e93eb9a 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/mainOAuth.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/mainOAuth.svelte @@ -3,13 +3,18 @@ import { CopyInput, Modal } from '$lib/components'; import { Button, + InputNumber, InputPassword, InputSwitch, InputText, InputTextarea } from '$lib/elements/forms'; import { updateOAuth } from '../updateOAuth'; - import { OAuthProvider, type Models as ConsoleModels } from '@appwrite.io/console'; + import { + OAuthProvider, + ProjectOAuth2OidcPrompt, + type Models as ConsoleModels + } from '@appwrite.io/console'; import type { AuthProvider } from '../updateOAuth'; import { oAuthProviders } from '$lib/stores/oauth-providers'; import { @@ -25,6 +30,7 @@ } from '@appwrite.io/pink-svelte'; import { IconDocument, IconPencil, IconUpload, IconX } from '@appwrite.io/pink-icons-svelte'; import { getApiEndpoint } from '$lib/stores/sdk'; + import OidcPromptPicker from './oidcPromptPicker.svelte'; const projectId = page.params.project; const region = page.params.region; @@ -44,14 +50,21 @@ let initialEnabled = false; let initialAppId: string | null = null; let initialDetailValues: Record = {}; + let oidcPrompt: ProjectOAuth2OidcPrompt[] = []; + let initialOidcPrompt: ProjectOAuth2OidcPrompt[] = []; + let oidcMaxAge: number | null = null; + let initialOidcMaxAge: number | null = null; + $: isOidc = provider?.key === OAuthProvider.Oidc; $: appIdParam = parameters.length >= 1 ? parameters[0] : null; $: additionalParams = parameters.slice(1); $: detailParams = additionalParams.filter((param) => !isSecretParam(param.$id)); $: secretParams = additionalParams.filter((param) => isSecretParam(param.$id)); $: basicDetailParams = provider?.key === OAuthProvider.Oidc - ? detailParams.filter((param) => !isOidcAdvancedParam(param.$id)) + ? detailParams.filter( + (param) => !isOidcAdvancedParam(param.$id) && !isOidcCustomParam(param.$id) + ) : detailParams; $: advancedDetailParams = provider?.key === OAuthProvider.Oidc @@ -66,11 +79,16 @@ normalizeFieldValue(fieldValues[param.$id]) !== (initialDetailValues[param.$id] ?? '') ); }); + $: hasOidcChanges = + isOidc && + ([...oidcPrompt].sort().join(',') !== [...initialOidcPrompt].sort().join(',') || + (oidcMaxAge ?? 0) !== (initialOidcMaxAge ?? 0)); $: nothingChanged = enabled === initialEnabled && normalizeFieldValue(appId) === normalizeFieldValue(initialAppId) && !hasSecretInput && - !hasDetailChanges; + !hasDetailChanges && + !hasOidcChanges; $: oAuthProvider = oAuthProviders[provider.key]; $: secretCardTitle = secretParams.length === 1 ? primaryName(secretParams[0]?.name ?? '') : 'Credentials'; @@ -90,6 +108,19 @@ ); p8PasteMode = {}; showSecretInput = !appId || (provider.key === OAuthProvider.Apple && !providerKeyId); + if (provider.key === OAuthProvider.Oidc) { + const raw = provider as Record; + initialOidcPrompt = Array.isArray(raw['prompt']) + ? ([...(raw['prompt'] as ProjectOAuth2OidcPrompt[])] as ProjectOAuth2OidcPrompt[]) + : []; + initialOidcMaxAge = + typeof raw['maxAge'] === 'number' && raw['maxAge'] > 0 ? raw['maxAge'] : null; + } else { + initialOidcPrompt = []; + initialOidcMaxAge = null; + } + oidcPrompt = [...initialOidcPrompt]; + oidcMaxAge = initialOidcMaxAge; error = undefined; } @@ -151,6 +182,11 @@ return id !== 'wellKnownURL' && id.toLowerCase().includes('url'); } + // prompt and maxAge get dedicated controls in the Advanced section + function isOidcCustomParam(id: string): boolean { + return id === 'prompt' || id === 'maxAge'; + } + async function handleP8FileUpload(id: string, event: Event) { const input = event.target as HTMLInputElement; const file = input.files?.[0]; @@ -198,6 +234,8 @@ appId, secret: buildSecret(), details: buildDetails(), + promptValues: isOidc ? oidcPrompt : undefined, + maxAge: isOidc ? (oidcMaxAge ?? 0) : undefined, enabled }); @@ -357,7 +395,7 @@ {/if} {/if} - {#if advancedDetailParams.length > 0} + {#if advancedDetailParams.length > 0 || isOidc} {#each advancedDetailParams as param} @@ -368,6 +406,17 @@ helper={helperText(param.hint)} bind:value={fieldValues[param.$id]} /> {/each} + {#if isOidc} + + + {/if} {/if} diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcPromptPicker.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcPromptPicker.svelte new file mode 100644 index 0000000000..242a7861ff --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcPromptPicker.svelte @@ -0,0 +1,42 @@ + + + + Prompt + + {#each options as option (option.val)} + toggle(option.val)}> + {option.label} + + {/each} + + diff --git a/src/routes/(console)/project-[region]-[project]/auth/updateOAuth.ts b/src/routes/(console)/project-[region]-[project]/auth/updateOAuth.ts index 17e62ddba1..9c777c1dc7 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/updateOAuth.ts +++ b/src/routes/(console)/project-[region]-[project]/auth/updateOAuth.ts @@ -7,6 +7,7 @@ import { sdk } from '$lib/stores/sdk'; import { OAuthProvider, ProjectOAuth2GooglePrompt, + ProjectOAuth2OidcPrompt, type Models as ConsoleModels } from '@appwrite.io/console'; @@ -25,7 +26,8 @@ type Args = { secret: string | null; details: Record; enabled: boolean; - promptValues?: ProjectOAuth2GooglePrompt[]; + promptValues?: ProjectOAuth2GooglePrompt[] | ProjectOAuth2OidcPrompt[]; + maxAge?: number; }; type Return = { @@ -51,7 +53,8 @@ async function updateProjectOAuth({ secret, details, enabled, - promptValues + promptValues, + maxAge }: Args) { const projectSdk = sdk.forProject(region, projectId).project; const parsedSecret = parseSecret(secret); @@ -86,6 +89,12 @@ async function updateProjectOAuth({ p8File: getSecret('p8File'), enabled }); + case OAuthProvider.Appwrite: + return projectSdk.updateOAuth2Appwrite({ + clientId: getAppId(), + clientSecret: getSecret(), + enabled + }); case OAuthProvider.Auth0: return projectSdk.updateOAuth2Auth0({ clientId: getAppId(), @@ -190,7 +199,7 @@ async function updateProjectOAuth({ return projectSdk.updateOAuth2Google({ clientId: getAppId(), clientSecret: getSecret(), - prompt: promptValues ?? [], + prompt: (promptValues as ProjectOAuth2GooglePrompt[]) ?? [], enabled }); case OAuthProvider.Keycloak: @@ -234,6 +243,8 @@ async function updateProjectOAuth({ authorizationURL: getDetail('authorizationURL'), tokenURL: getDetail('tokenUrl'), userInfoURL: getDetail('userInfoUrl'), + prompt: (promptValues as ProjectOAuth2OidcPrompt[]) ?? [], + maxAge: maxAge ?? 0, enabled }); case OAuthProvider.Okta: @@ -353,7 +364,8 @@ export async function updateOAuth({ secret, details, enabled, - promptValues + promptValues, + maxAge }: Args): Promise { try { if (!isValueOfStringEnum(OAuthProvider, provider.key)) { @@ -368,7 +380,8 @@ export async function updateOAuth({ secret, details, enabled, - promptValues + promptValues, + maxAge }); await invalidate(Dependencies.PROJECT); From 395a26886bfd2f3a0b333a199394c498b52b87fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 10 Jul 2026 10:40:33 +0200 Subject: [PATCH 3/3] Code quality improvements --- .../auth/(providers)/oidcPromptPicker.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcPromptPicker.svelte b/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcPromptPicker.svelte index 242a7861ff..6cbc733fbc 100644 --- a/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcPromptPicker.svelte +++ b/src/routes/(console)/project-[region]-[project]/auth/(providers)/oidcPromptPicker.svelte @@ -34,7 +34,7 @@ Prompt {#each options as option (option.val)} - toggle(option.val)}> + toggle(option.val)}> {option.label} {/each}