diff --git a/src/lib/components/navbar.svelte b/src/lib/components/navbar.svelte
index 37813d9172..1178cd1bfd 100644
--- a/src/lib/components/navbar.svelte
+++ b/src/lib/components/navbar.svelte
@@ -34,6 +34,7 @@
IconCreditCard,
IconCurrencyDollar,
IconGlobeAlt,
+ IconKey,
IconLogoutRight,
IconMenuAlt4,
IconMode,
@@ -340,6 +341,21 @@
)}
on:click={() => toggle()}>
Domains
+
+ {#if currentProject}
+ toggle()}>
+ API keys
+ {/if}
{/if}
@@ -402,6 +418,21 @@
leadingIcon: IconUser,
href: resolve('/(console)/account')
},
+ ...(resolvedProfile.showExtendedAccountsMenu && currentProject
+ ? [
+ {
+ name: 'API keys',
+ leadingIcon: IconKey,
+ href: resolve(
+ '/(console)/project-[region]-[project]/settings/api-keys',
+ {
+ region: currentProject.region,
+ project: currentProject.$id
+ }
+ )
+ }
+ ]
+ : []),
{
name: 'Sign out',
leadingIcon: IconLogoutRight,
diff --git a/src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte b/src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte
index 4c9bb81508..f66793caeb 100644
--- a/src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte
+++ b/src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte
@@ -1,5 +1,5 @@
+
+
+ {getPageTitle(page.data?.project?.name, 'API Keys', resolvedProfile.platform)}
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/settings/api-keys/+page.svelte b/src/routes/(console)/project-[region]-[project]/settings/api-keys/+page.svelte
new file mode 100644
index 0000000000..ca50bac97e
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/settings/api-keys/+page.svelte
@@ -0,0 +1,27 @@
+
+
+
+
+ {#if $canWriteKeys}
+
+ {/if}
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/settings/api-keys/+page.ts b/src/routes/(console)/project-[region]-[project]/settings/api-keys/+page.ts
new file mode 100644
index 0000000000..36fa8bbf52
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/settings/api-keys/+page.ts
@@ -0,0 +1,12 @@
+import { Dependencies } from '$lib/constants';
+import { sdk } from '$lib/stores/sdk';
+import type { PageLoad } from './$types';
+
+export const load: PageLoad = async ({ params, depends }) => {
+ depends(Dependencies.KEYS);
+ return {
+ keys: await sdk.forConsole.projects.listKeys({
+ projectId: params.project
+ })
+ };
+};
diff --git a/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/+page.ts b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/+page.ts
new file mode 100644
index 0000000000..84421d00e6
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/+page.ts
@@ -0,0 +1,25 @@
+import Header from './header.svelte';
+import Breadcrumbs from './breadcrumbs.svelte';
+import { sdk } from '$lib/stores/sdk';
+import { Dependencies } from '$lib/constants';
+import type { PageLoad } from './$types';
+
+export const load: PageLoad = async ({ params, depends }) => {
+ depends(Dependencies.KEY);
+
+ const key = await sdk.forConsole.projects.getKey({
+ projectId: params.project,
+ keyId: params.key
+ });
+ if (key.expire) {
+ key.expire = new Date(key.expire).toISOString().slice(0, 23);
+ } else {
+ key.expire = undefined;
+ }
+
+ return {
+ header: Header,
+ breadcrumbs: Breadcrumbs,
+ key
+ };
+};
diff --git a/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/+page@project-[region]-[project].svelte b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/+page@project-[region]-[project].svelte
new file mode 100644
index 0000000000..60c780e334
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/+page@project-[region]-[project].svelte
@@ -0,0 +1,10 @@
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/breadcrumbs.svelte b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/breadcrumbs.svelte
new file mode 100644
index 0000000000..bff744fbc7
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/breadcrumbs.svelte
@@ -0,0 +1,41 @@
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/header.svelte b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/header.svelte
new file mode 100644
index 0000000000..aa12667f7f
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/header.svelte
@@ -0,0 +1,41 @@
+
+
+
+
+
+ {$key?.name}
+
+
+ {#if $key?.secret}
+
+
+
+ API secret
+
+
+ {/if}
+ {#if $projectRegion}
+
+ {/if}
+
+
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/store.ts b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/store.ts
new file mode 100644
index 0000000000..5a1a9f936e
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/settings/api-keys/[key]/store.ts
@@ -0,0 +1,5 @@
+import { page } from '$app/stores';
+import { derived } from 'svelte/store';
+import type { Models } from '@appwrite.io/console';
+
+export const key = derived(page, ($page) => $page.data.key as Models.Key);
diff --git a/src/routes/(console)/project-[region]-[project]/settings/api-keys/create/+page@project-[region]-[project].svelte b/src/routes/(console)/project-[region]-[project]/settings/api-keys/create/+page@project-[region]-[project].svelte
new file mode 100644
index 0000000000..ba22cb1841
--- /dev/null
+++ b/src/routes/(console)/project-[region]-[project]/settings/api-keys/create/+page@project-[region]-[project].svelte
@@ -0,0 +1,9 @@
+
+
+
diff --git a/src/routes/(console)/project-[region]-[project]/settings/header.svelte b/src/routes/(console)/project-[region]-[project]/settings/header.svelte
index d7a715c2c8..9cee8d76f8 100644
--- a/src/routes/(console)/project-[region]-[project]/settings/header.svelte
+++ b/src/routes/(console)/project-[region]-[project]/settings/header.svelte
@@ -8,6 +8,7 @@
import { canWriteProjects } from '$lib/stores/roles';
import { isCloud } from '$lib/system';
import { Typography } from '@appwrite.io/pink-svelte';
+ import { resolvedProfile } from '$lib/profiles/index.svelte';
const path = `${base}/project-${page.params.region}-${page.params.project}/settings`;
const tabs: TabElement[] = [
@@ -16,6 +17,12 @@
title: 'Overview',
event: 'overview'
},
+ {
+ href: `${path}/api-keys`,
+ title: 'API keys',
+ event: 'api-keys',
+ disabled: !resolvedProfile.showExtendedAccountsMenu
+ },
{
href: `${path}/domains`,
title: 'Custom domains',