73a3279d5c
Hop-State: A_06FPAHQDE2YC3AQWGQGNQN0 Hop-Proposal: R_06FPAHP3Q77W9A2D641H4SR Hop-Task: T_06FPAH33SHXWSFZ2V45R2Z8 Hop-Attempt: AT_06FPAH33SGNKEM8JTS1KX70
93 lines
2.1 KiB
TypeScript
93 lines
2.1 KiB
TypeScript
import {
|
|
StuffboxClient,
|
|
createPkcePair,
|
|
generateState,
|
|
type Asset,
|
|
type StuffboxScope,
|
|
type TokenSet,
|
|
} from "@gnosyslabs/stuffbox-sdk";
|
|
|
|
const stuffbox = new StuffboxClient({ baseUrl: "https://stuffbox.xyz" });
|
|
|
|
export interface PendingConnection {
|
|
clientId: string;
|
|
callbackUrl: string;
|
|
codeVerifier: string;
|
|
state: string;
|
|
}
|
|
|
|
interface BeginConnectionInput {
|
|
callbackUrl: string;
|
|
scopes: readonly StuffboxScope[];
|
|
clientId?: string;
|
|
savePending(value: PendingConnection): Promise<void>;
|
|
}
|
|
|
|
export async function beginConnection(
|
|
input: BeginConnectionInput,
|
|
): Promise<string> {
|
|
const pkce = await createPkcePair();
|
|
const state = generateState();
|
|
const common = {
|
|
callbackUrl: input.callbackUrl,
|
|
codeChallenge: pkce.challenge,
|
|
scopes: input.scopes,
|
|
state,
|
|
};
|
|
const connection = await stuffbox.createConnectionRequest(
|
|
input.clientId
|
|
? { ...common, clientId: input.clientId }
|
|
: { ...common, selfHosted: true },
|
|
);
|
|
|
|
await input.savePending({
|
|
clientId: connection.clientId,
|
|
callbackUrl: connection.callbackUrl,
|
|
codeVerifier: pkce.verifier,
|
|
state,
|
|
});
|
|
|
|
return connection.authorizationUrl;
|
|
}
|
|
|
|
interface FinishConnectionInput {
|
|
code: string;
|
|
returnedState: string;
|
|
pending: PendingConnection;
|
|
}
|
|
|
|
export async function finishConnection(
|
|
input: FinishConnectionInput,
|
|
): Promise<TokenSet> {
|
|
if (input.returnedState !== input.pending.state) {
|
|
throw new Error("Stuffbox connection state did not match");
|
|
}
|
|
|
|
return stuffbox.exchangeAuthorizationCode({
|
|
clientId: input.pending.clientId,
|
|
code: input.code,
|
|
codeVerifier: input.pending.codeVerifier,
|
|
redirectUri: input.pending.callbackUrl,
|
|
});
|
|
}
|
|
|
|
export async function loadEntireLibrary(accessToken: string): Promise<Asset[]> {
|
|
const media = new StuffboxClient({
|
|
baseUrl: "https://stuffbox.xyz",
|
|
accessToken,
|
|
});
|
|
const assets: Asset[] = [];
|
|
let cursor: string | undefined;
|
|
|
|
do {
|
|
const page = await media.listAssets({
|
|
limit: 100,
|
|
...(cursor ? { cursor } : {}),
|
|
});
|
|
assets.push(...page.items);
|
|
cursor = page.nextCursor;
|
|
} while (cursor);
|
|
|
|
return assets;
|
|
}
|