diff --git a/src/auth/scope-utils.ts b/src/auth/scope-utils.ts index 2ca2613..9bc354c 100644 --- a/src/auth/scope-utils.ts +++ b/src/auth/scope-utils.ts @@ -1,3 +1,5 @@ +import { Did } from "@atcute/lexicons"; + import { agent, sessions } from "./state"; export const SPACE_READ_SCOPE_ID = "space-read" as const; @@ -64,12 +66,18 @@ export const hasUserScope = (scopeId: ScopeId): boolean => { const currentAgent = agent(); if (!currentAgent) return false; + return hasAccountScope(currentAgent.sub, scopeId); +}; + +export const hasAccountScope = (did: Did, scopeId: ScopeId): boolean => { + const currentAgent = agent(); + const configuredScope = GRANULAR_SCOPES.find(({ id }) => id === scopeId)?.scope; - if (configuredScope && currentAgent.session.token.scope) { + if (currentAgent?.sub === did && configuredScope && currentAgent.session.token.scope) { return currentAgent.session.token.scope.split(" ").includes(configuredScope); } - const grantedScopes = sessions[currentAgent.sub]?.grantedScopes; + const grantedScopes = sessions[did]?.grantedScopes; if (!grantedScopes) return true; return hasScope(grantedScopes, scopeId); }; diff --git a/src/components/create/file-upload.tsx b/src/components/create/file-upload.tsx index 32faa14..d7e42d0 100644 --- a/src/components/create/file-upload.tsx +++ b/src/components/create/file-upload.tsx @@ -1,8 +1,9 @@ import { Client } from "@atcute/client"; +import { Did } from "@atcute/lexicons"; +import { getSession, OAuthUserAgent } from "@atcute/oauth-browser-client"; import { remove } from "@mary/exif-rm"; import { createSignal, onCleanup, Show } from "solid-js"; -import { agent } from "../../auth/state"; import { formatFileSize } from "../../utils/format"; import { Button } from "../button.jsx"; import { TextInput } from "../text-input.jsx"; @@ -10,6 +11,7 @@ import { editorInstance } from "./state"; export const FileUpload = (props: { file: File; + repo: Did; blobInput: HTMLInputElement; onClose: () => void; }) => { @@ -31,7 +33,7 @@ export const FileUpload = (props: { if (exifRemoved !== null) blob = new Blob([exifRemoved as BlobPart], { type: blob.type }); } - const rpc = new Client({ handler: agent()! }); + const rpc = new Client({ handler: new OAuthUserAgent(await getSession(props.repo)) }); setUploading(true); const res = await rpc.post("com.atproto.repo.uploadBlob", { input: blob, diff --git a/src/components/create/index.tsx b/src/components/create/index.tsx index ba2b0b6..31e9910 100644 --- a/src/components/create/index.tsx +++ b/src/components/create/index.tsx @@ -14,7 +14,7 @@ import { Suspense, } from "solid-js"; -import { hasUserScope } from "../../auth/scope-utils"; +import { hasAccountScope, hasUserScope } from "../../auth/scope-utils"; import { agent, sessions } from "../../auth/state"; import { Button } from "../button.jsx"; import { Modal } from "../modal.jsx"; @@ -48,8 +48,14 @@ export const RecordEditor = (props: { const [openConfirmDialog, setOpenConfirmDialog] = createSignal(false); const [validate, setValidate] = createSignal(undefined); const [recreate, setRecreate] = createSignal(false); + const [selectedRepo, setSelectedRepo] = createSignal(agent()?.sub); const hasPermission = () => !props.scope || hasUserScope(props.scope); + const uploadRepo = () => (props.create ? selectedRepo() : agent()?.sub); + const canUploadBlob = () => { + const repo = uploadRepo(); + return repo ? hasAccountScope(repo, "blob") : false; + }; const [isMaximized, setIsMaximized] = createSignal(false); const [isMinimized, setIsMinimized] = createSignal(false); const [collectionError, setCollectionError] = createSignal(""); @@ -58,6 +64,10 @@ export const RecordEditor = (props: { let formRef!: HTMLFormElement; let insertMenuRef!: HTMLDivElement; + createEffect(() => { + setSelectedRepo(agent()?.sub); + }); + createEffect(() => { if (openInsertMenu()) { const handleClickOutside = (e: MouseEvent) => { @@ -281,12 +291,12 @@ export const RecordEditor = (props: { class="dark:bg-dark-100 max-w-40 truncate rounded-md border border-neutral-200 bg-white px-1 py-1 select-none focus:outline-1 focus:outline-neutral-400 dark:border-neutral-600 dark:focus:outline-neutral-400" name="repo" id="repo" + value={selectedRepo()} + onChange={(e) => setSelectedRepo(e.currentTarget.value as Did)} > {(session) => ( - + )} @@ -367,19 +377,19 @@ export const RecordEditor = (props: { @@ -401,6 +411,7 @@ export const RecordEditor = (props: { > setOpenUpload(false)} />