aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/(app)/settings
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-11-04 14:38:22 -0700
committerAdam Soltys <[email protected]>2026-11-04 14:38:22 -0700
commit976473a781f1bcda7ba02fee9db122e163243e2b (patch)
tree8edb78375f98dbb7d9e2d67bfa91293517f40017 /src/routes/(app)/settings
parentd6f63cb4b75aeeaeb9b4306a876d63ed84a22f74 (diff)
downloadcoinos-ui-976473a781f1bcda7ba02fee9db122e163243e2b.tar.gz
coinos-ui-976473a781f1bcda7ba02fee9db122e163243e2b.zip
settings: show the read-only and full access API tokens under security
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/routes/(app)/settings')
-rw-r--r--src/routes/(app)/settings/security/+page.server.ts7
-rw-r--r--src/routes/(app)/settings/security/+page.svelte49
2 files changed, 55 insertions, 1 deletions
diff --git a/src/routes/(app)/settings/security/+page.server.ts b/src/routes/(app)/settings/security/+page.server.ts
index 4145935e..e7cc93a3 100644
--- a/src/routes/(app)/settings/security/+page.server.ts
+++ b/src/routes/(app)/settings/security/+page.server.ts
@@ -1,4 +1,11 @@
import updateUser from "$lib/settings";
+import { auth, get } from "$lib/utils";
+
+export const load = async ({ cookies }) => {
+ const token = cookies.get("token");
+ const ro = token ? await get("/ro", auth(cookies)) : undefined;
+ return { ro, token };
+};
export const actions = {
default: updateUser,
diff --git a/src/routes/(app)/settings/security/+page.svelte b/src/routes/(app)/settings/security/+page.svelte
index 8c38bca1..b774d919 100644
--- a/src/routes/(app)/settings/security/+page.svelte
+++ b/src/routes/(app)/settings/security/+page.svelte
@@ -10,7 +10,7 @@
import { page } from "$app/stores";
let { data } = $props();
- let { user } = $derived(data);
+ let { user, ro, token: apiToken } = $derived(data);
let { id } = user;
let { haspin } = $derived(user);
@@ -23,6 +23,7 @@
pin = $state(""),
revealSeed,
revealNsec = $state(),
+ revealToken = $state(),
token = $state(""),
setting2fa = $state(),
settingPin = $state(),
@@ -232,6 +233,52 @@
{/if}
</div>
+{#snippet tokenBox(value)}
+ <div
+ class="bg-primary text-primary-content rounded-lg p-4 flex gap-4 items-center"
+ >
+ <div class="w-full break-all">{value}</div>
+ <button type="button" class="ml-auto" onclick={() => copy(value)}>
+ <iconify-icon noobserver icon="ph:copy-bold" width="32"></iconify-icon>
+ </button>
+ </div>
+{/snippet}
+
+{#if ro}
+ <div class="space-y-4">
+ <div>
+ <span class="font-bold mb-1">{$t("user.settings.apiTokens")}</span>
+ <p class="text-secondary">
+ {$t("user.settings.apiTokensDescription")}
+ <a href="/docs" class="underline">{$t("user.settings.apiDocs")}</a>
+ </p>
+ </div>
+
+ <div>
+ <span class="font-bold mb-1">{$t("user.settings.readOnlyToken")}</span>
+ <p class="text-secondary mb-2">
+ {$t("user.settings.readOnlyTokenDescription")}
+ </p>
+ {@render tokenBox(ro)}
+ </div>
+
+ <div>
+ <span class="font-bold mb-1">{$t("user.settings.fullAccessToken")}</span>
+ <p class="text-secondary mb-2">
+ {$t("user.settings.fullAccessTokenDescription")}
+ </p>
+ {#if revealToken}
+ {@render tokenBox(apiToken)}
+ {:else}
+ <button type="button" class="btn" onclick={() => (revealToken = true)}>
+ <iconify-icon noobserver icon="ph:key-bold" width="32"></iconify-icon>
+ {$t("user.settings.revealToken")}
+ </button>
+ {/if}
+ </div>
+ </div>
+{/if}
+
<div>
<a href={`/account/savings`} class="contents">
<button class="btn btn-lg w-full rounded-2xl whitespace-nowrap">