From 68ee7a8edb7c3117214f8b0f9ce53612d1e9dc89 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 30 Mar 2026 08:34:44 +0530 Subject: [PATCH 1/3] render deprecated api key scopes --- src/lib/constants.ts | 27 ++++-- .../overview/(components)/keyDetails.svelte | 6 +- .../overview/api-keys/scopes.svelte | 92 +++++-------------- 3 files changed, 44 insertions(+), 81 deletions(-) diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 2cb52605e3..6c28da6668 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -155,12 +155,15 @@ export const defaultRoles: string[] = ['owner']; // these are kept for backwards compatibility with keys and events that already exists. // for the new ones, we use the new terminology. -export const scopes: { +export type ScopeDefinition = { scope: string; description: string; category: string; icon: string; -}[] = [ + deprecated?: boolean; +}; + +export const scopes: ScopeDefinition[] = [ { scope: 'sessions.write', description: "Access to create, update and delete your project's sessions", @@ -207,13 +210,15 @@ export const scopes: { scope: 'collections.read', description: "Access to read your project's database collections", category: 'Database', - icon: 'database' + icon: 'database', + deprecated: true }, { scope: 'collections.write', description: "Access to create, update, and delete your project's database collections", category: 'Database', - icon: 'database' + icon: 'database', + deprecated: true }, { scope: 'tables.read', @@ -231,14 +236,16 @@ export const scopes: { scope: 'attributes.read', description: "Access to read your project's database collection's attributes", category: 'Database', - icon: 'database' + icon: 'database', + deprecated: true }, { scope: 'attributes.write', description: "Access to create, update, and delete your project's database collection's attributes", category: 'Database', - icon: 'database' + icon: 'database', + deprecated: true }, { scope: 'columns.read', @@ -268,13 +275,15 @@ export const scopes: { scope: 'documents.read', description: "Access to read your project's database documents", category: 'Database', - icon: 'database' + icon: 'database', + deprecated: true }, { scope: 'documents.write', description: "Access to create, update, and delete your project's database documents", category: 'Database', - icon: 'database' + icon: 'database', + deprecated: true }, { scope: 'rows.read', @@ -466,7 +475,7 @@ export const scopes: { } ]; -export const cloudOnlyBackupScopes = [ +export const cloudOnlyBackupScopes: ScopeDefinition[] = [ { scope: 'policies.read', description: 'Access to read your database backup policies', diff --git a/src/routes/(console)/project-[region]-[project]/overview/(components)/keyDetails.svelte b/src/routes/(console)/project-[region]-[project]/overview/(components)/keyDetails.svelte index 909e7a6783..da2487f864 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/(components)/keyDetails.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/(components)/keyDetails.svelte @@ -16,7 +16,6 @@ import { symmetricDifference } from '$lib/helpers/array'; import Scopes from '../api-keys/scopes.svelte'; import { InteractiveText, Layout, Typography } from '@appwrite.io/pink-svelte'; - import { getEffectiveScopes } from '../api-keys/scopes.svelte'; export let key: Models.DevKey | Models.Key; export let keyType: 'api' | 'dev' = 'api'; @@ -163,8 +162,6 @@ {#if isApiKey}
{@const apiKey = asApiKey(key)} - {@const apiKeyCorrectScopes = getEffectiveScopes(apiKey.scopes)} - {@const currentEffective = scopes ? getEffectiveScopes(scopes) : null} Scopes You can choose which permission scope to grant your application. It is a best practice @@ -178,8 +175,7 @@ diff --git a/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte b/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte index f314419f85..31b8352f34 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte @@ -31,29 +31,21 @@ import { Button } from '$lib/elements/forms'; import { symmetricDifference } from '$lib/helpers/array'; import { scopes as allScopes, cloudOnlyBackupScopes } from '$lib/constants'; - import { Accordion, Divider, Layout, Selector } from '@appwrite.io/pink-svelte'; + import { Accordion, Badge, Divider, Layout, Selector } from '@appwrite.io/pink-svelte'; import type { Scopes } from '@appwrite.io/console'; export let scopes: Scopes[]; - const baseFilteredScopes = allScopes.filter((scope) => { - const val = scope.scope; - if (!val) return false; - - const legacyPrefixes = ['collections.', 'attributes.', 'documents.']; - return !legacyPrefixes.some((prefix) => val.startsWith(prefix)); - }); - // insert cloud-only scopes right after databases.write - const databasesWriteIndex = baseFilteredScopes.findIndex((s) => s.scope === 'databases.write'); + const databasesWriteIndex = allScopes.findIndex((s) => s.scope === 'databases.write'); const filteredScopes = isCloud && databasesWriteIndex !== -1 ? [ - ...baseFilteredScopes.slice(0, databasesWriteIndex + 1), + ...allScopes.slice(0, databasesWriteIndex + 1), ...cloudOnlyBackupScopes, - ...baseFilteredScopes.slice(databasesWriteIndex + 1) + ...allScopes.slice(databasesWriteIndex + 1) ] - : baseFilteredScopes; + : allScopes; // include all scopes const scopeCatalog = new Set([ @@ -90,9 +82,8 @@ onMount(() => { scopes.forEach((scope) => { - const newerScope = toNewerScope(scope); - if (newerScope in activeScopes) { - activeScopes[newerScope] = true; + if (scope in activeScopes) { + activeScopes[scope] = true; } }); @@ -111,36 +102,11 @@ } } - function toNewerScope(scope: string): string { - for (const pair of compatPairs) { - if (scope.startsWith(pair.legacy)) { - return scope.replace(pair.legacy, pair.newer); - } - } - return scope; - } - - function getAllScopeVariants(scope: string): string[] { - const variants = new Set([scope]); - - for (const pair of compatPairs) { - if (scope.startsWith(pair.newer)) { - variants.add(scope.replace(pair.newer, pair.legacy)); - } else if (scope.startsWith(pair.legacy)) { - variants.add(scope.replace(pair.legacy, pair.newer)); - } - } - - return Array.from(variants); - } - function categoryState(category: string, s: string[]): boolean | 'indeterminate' { const scopesByCategory = filteredScopes.filter((n) => n.category === category); - - const activeInCategory = scopesByCategory.filter((scopeItem) => { - const newerScope = scopeItem.scope; - return s.some((scope) => toNewerScope(scope) === newerScope); - }); + const activeInCategory = scopesByCategory.filter((scopeItem) => + s.includes(scopeItem.scope as Scopes) + ); if (activeInCategory.length === 0) { return false; @@ -161,20 +127,9 @@ } function generateSyncedScopes(activeScopesObj: Record): Scopes[] { - const result = new Set(); - - Object.entries(activeScopesObj).forEach(([scope, isActive]) => { - if (isActive) { - const variants = getAllScopeVariants(scope); - variants.forEach((variant) => { - if (scopeCatalog.has(variant)) { - result.add(variant); - } - }); - } - }); - - return Array.from(result) as Scopes[]; + return Object.entries(activeScopesObj) + .filter(([scope, isActive]) => isActive && scopeCatalog.has(scope)) + .map(([scope]) => scope as Scopes); } $: { @@ -203,9 +158,7 @@ {@const checked = categoryState(category, scopes)} {@const isLastItem = index === categories.length - 1} {@const scopesLength = filteredScopes.filter( - (n) => - n.category === category && - scopes.some((scope) => toNewerScope(scope) === n.scope) + (n) => n.category === category && scopes.includes(n.scope as Scopes) ).length} onCategoryChange(event, category)}> {#each filteredScopes.filter((s) => s.category === category) as scope} - + + + {#if scope.deprecated} + + {/if} + {/each} From 043628cc25cb369cb7682619f4e9436651851eb8 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 30 Mar 2026 08:45:28 +0530 Subject: [PATCH 2/3] address deprecated scope review feedback --- .../overview/(components)/table.svelte | 3 +-- .../project-[region]-[project]/overview/api-keys/scopes.svelte | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte b/src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte index 535be9bd6d..198397e949 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte @@ -11,7 +11,6 @@ import { Badge, Layout, Table } from '@appwrite.io/pink-svelte'; import DeleteBatch from './deleteBatch.svelte'; import { capitalize } from '$lib/helpers/string'; - import { getEffectiveScopes } from '../api-keys/scopes.svelte'; let { keyType = 'api', @@ -31,7 +30,7 @@ function getApiKeyScopeCount(key: Models.Key | Models.DevKey) { const apiKey = key as Models.Key; - return getEffectiveScopes(apiKey.scopes).length; + return apiKey.scopes.length; } function getExpiryDetails(key: Models.Key | Models.DevKey): { diff --git a/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte b/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte index 31b8352f34..1a4c8241cb 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte @@ -120,7 +120,7 @@ function onCategoryChange(event: CustomEvent, category: Category) { if (event.detail === 'indeterminate') return; filteredScopes.forEach((s) => { - if (s.category === category) { + if (s.category === category && !s.deprecated) { activeScopes[s.scope] = event.detail; } }); From 8a7736c9718ebf660049664bbdc41d97b8a8417a Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Mon, 30 Mar 2026 08:47:43 +0530 Subject: [PATCH 3/3] improve deprecated scope accessibility --- .../project-[region]-[project]/overview/api-keys/scopes.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte b/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte index 1a4c8241cb..70608e2f0a 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte @@ -173,7 +173,7 @@ {#if scope.deprecated}