diff --git a/web/src/lib/api/spindle.ts b/web/src/lib/api/spindle.ts new file mode 100644 index 00000000..ee85c8ac --- /dev/null +++ b/web/src/lib/api/spindle.ts @@ -0,0 +1,58 @@ +import type { OAuthUserAgent } from "@atcute/oauth-browser-client"; +import { + createAppviewClient, + authedGet, + authedPost, + type AppviewContext +} from "./appview"; +import type { XrpcRequestInit } from "./client"; + +// The spindle is a service-auth'd xrpc host just like the appview: the browser +// mints a per-call token with aud = did:web: and lxm = the method. +// Secrets live on the spindle (the CI runner needs them) and are keyed by the +// repo's at-uri, which the spindle resolves to a repoDid. +export type SpindleContext = AppviewContext; + +export const createSpindleClient = ( + host: string, + agent: OAuthUserAgent, + fetch?: typeof globalThis.fetch +): SpindleContext => createAppviewClient({ apiUrl: `https://${host}`, agent, fetch }); + +// mirrors sh.tangled.repo.listSecrets#secret — values are never returned. +export interface Secret { + repo: string; + key: string; + createdAt: string; + createdBy: string; +} + +const LIST_SECRETS = "sh.tangled.repo.listSecrets"; +const ADD_SECRET = "sh.tangled.repo.addSecret"; +const REMOVE_SECRET = "sh.tangled.repo.removeSecret"; + +export const listSecrets = async ( + ctx: SpindleContext, + repoUri: string, + init?: XrpcRequestInit +): Promise => { + const res = await authedGet<{ secrets?: Secret[] }>(ctx, LIST_SECRETS, { repo: repoUri }, init); + return res.secrets ?? []; +}; + +export const addSecret = ( + ctx: SpindleContext, + repoUri: string, + key: string, + value: string, + init?: XrpcRequestInit +): Promise => + authedPost(ctx, ADD_SECRET, { repo: repoUri, key, value }, init).then(() => undefined); + +export const removeSecret = ( + ctx: SpindleContext, + repoUri: string, + key: string, + init?: XrpcRequestInit +): Promise => + authedPost(ctx, REMOVE_SECRET, { repo: repoUri, key }, init).then(() => undefined); diff --git a/web/src/routes/[handle]/[repo]/settings/pipelines/+page.svelte b/web/src/routes/[handle]/[repo]/settings/pipelines/+page.svelte index daf19d3b..ab7fad5f 100644 --- a/web/src/routes/[handle]/[repo]/settings/pipelines/+page.svelte +++ b/web/src/routes/[handle]/[repo]/settings/pipelines/+page.svelte @@ -1,10 +1,16 @@ @@ -51,12 +73,17 @@ - + {:else} + + {/if} @@ -70,28 +97,61 @@ separator > {#snippet action()} - + {/snippet} - - {#each secrets as secret (secret.name)} - - {#snippet label()} - - - {secret.name} - - - {secret.added} - - {secret.by} + {#if loaded.error} + + {/if} + {#if remove.error} + + {/if} + + {#if !spindleHost} + + {:else if loaded.loading} + + {#each [0, 1] as row (row)} +
+
+ + +
+ +
+ {/each} +
+ {:else if (loaded.data?.length ?? 0) === 0} + + {:else if loaded.data} + + {#each loaded.data as secret (secret.key)} + + {#snippet label()} + + + {secret.key} + + + Added + + -
- {/snippet} - -
- {/each} -
+ {/snippet} + + + {/each} + + {/if} diff --git a/web/src/routes/[handle]/[repo]/settings/pipelines/secrets/new/+page.svelte b/web/src/routes/[handle]/[repo]/settings/pipelines/secrets/new/+page.svelte index 38944be7..d1c9d4c3 100644 --- a/web/src/routes/[handle]/[repo]/settings/pipelines/secrets/new/+page.svelte +++ b/web/src/routes/[handle]/[repo]/settings/pipelines/secrets/new/+page.svelte @@ -1,8 +1,12 @@ + {#if create.error} + + {/if} + @@ -39,6 +56,14 @@ - +