delegation: preset scopes grant identity & account

Lewis: May this revision serve well! <lu5a@proton.me>
This commit is contained in:
Lewis
2026-06-27 23:11:24 +03:00
parent a171518290
commit ab4eba6dc4
12 changed files with 315 additions and 70 deletions
@@ -42,6 +42,7 @@
let controllers = $state<Controller[]>([])
let controlledAccounts = $state<ControlledAccount[]>([])
let scopePresets = $state<ScopePreset[]>([])
let defaultScopes = $state('')
let hasControllers = $derived(controllers.length > 0)
let controlsAccounts = $derived(controlledAccounts.length > 0)
@@ -50,7 +51,7 @@
let showAddController = $state(false)
let addControllerIdentifier = $state('')
let addControllerScopes = $state('atproto')
let addControllerScopes = $state('')
let addingController = $state(false)
let addControllerConfirmed = $state(false)
let resolvedController = $state<{ did: string; handle?: string; pdsUrl?: string; isLocal: boolean } | null>(null)
@@ -119,7 +120,7 @@
let showCreateDelegated = $state(false)
let newDelegatedHandle = $state('')
let newDelegatedEmail = $state('')
let newDelegatedScopes = $state('atproto')
let newDelegatedScopes = $state('')
let creatingDelegated = $state(false)
onMount(async () => {
@@ -168,6 +169,9 @@
description: p.description,
scopes: unsafeAsScopeSet(p.scopes)
}))
defaultScopes = scopePresets.find(p => p.name === 'owner')?.scopes ?? scopePresets[0]?.scopes ?? ''
addControllerScopes = defaultScopes
newDelegatedScopes = defaultScopes
}
}
@@ -181,7 +185,7 @@
if (result.ok) {
toast.success($_('delegation.controllerAdded'))
addControllerIdentifier = ''
addControllerScopes = 'atproto'
addControllerScopes = defaultScopes
addControllerConfirmed = false
resolvedController = null
showAddController = false
@@ -214,7 +218,7 @@
toast.success($_('delegation.accountCreated', { values: { handle: result.value.handle } }))
newDelegatedHandle = ''
newDelegatedEmail = ''
newDelegatedScopes = 'atproto'
newDelegatedScopes = defaultScopes
showCreateDelegated = false
await loadControlledAccounts()
}
@@ -224,7 +228,6 @@
function getScopeLabel(scopes: ScopeSet): string {
const preset = scopePresets.find(p => p.scopes === scopes)
if (preset) return preset.label
if ((scopes as string) === 'atproto') return $_('delegation.scopeOwner')
if ((scopes as string) === '') return $_('delegation.scopeViewer')
return $_('delegation.scopeCustom')
}
+2 -2
View File
@@ -3,7 +3,7 @@ const OAUTH_VERIFIER_KEY = "tranquil_pds_oauth_verifier";
const DPOP_KEY_STORE = "tranquil_pds_dpop_keys";
const DPOP_NONCE_KEY = "tranquil_pds_dpop_nonce";
const SCOPES = [
export const SCOPES = [
"atproto",
"repo:*?action=create",
"repo:*?action=update",
@@ -16,7 +16,7 @@ const SCOPES = [
const CLIENT_ID =
!(import.meta.env.DEV) || globalThis.location?.hostname !== 'localhost'
? `${globalThis.location.origin}/oauth-client-metadata.json`
: `http://localhost/?scope=${SCOPES}`;
: `http://localhost/?scope=${encodeURIComponent(SCOPES)}`;
const REDIRECT_URI = `${globalThis.location.origin}/app/`;
+2 -2
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import AuthenticatedRoute from '../components/AuthenticatedRoute.svelte'
import { navigate } from '../lib/router.svelte'
import { generateCodeVerifier, generateCodeChallenge, saveOAuthState, generateState, createDPoPProofForRequest, setDPoPNonce } from '../lib/oauth'
import { generateCodeVerifier, generateCodeChallenge, saveOAuthState, generateState, createDPoPProofForRequest, setDPoPNonce, SCOPES } from '../lib/oauth'
import { _ } from '../lib/i18n'
import type { Session, DelegationControlledAccount } from '../lib/types/api'
import type { AuthenticatedClient } from '../lib/authenticated-client'
@@ -54,7 +54,7 @@
client_id: `${hostname}/oauth-client-metadata.json`,
redirect_uri: `${hostname}/app/`,
response_type: 'code',
scope: 'atproto',
scope: SCOPES,
state: state,
code_challenge: codeChallenge,
code_challenge_method: 'S256',