40 lines
1.2 KiB
TypeScript
40 lines
1.2 KiB
TypeScript
'use client';
|
|
|
|
import { getOAuthClientId, getOAuthRedirectUri, getPublicApiOrigin } from '@/lib/env';
|
|
import { createPKCEPair } from '@/lib/oauth/pkce';
|
|
|
|
const VERIFIER_KEY = 'smart_oauth_pkce_verifier';
|
|
|
|
/** 跳转浏览器授权页(与 GET /oauth/authorize 一致);PKCE verifier 写入 sessionStorage,回调页取出换 token。 */
|
|
export async function redirectToAuthorize(): Promise<void> {
|
|
const { verifier, challenge } = await createPKCEPair();
|
|
if (typeof window !== 'undefined') {
|
|
sessionStorage.setItem(VERIFIER_KEY, verifier);
|
|
}
|
|
const params = new URLSearchParams({
|
|
response_type: 'code',
|
|
client_id: getOAuthClientId(),
|
|
redirect_uri: getOAuthRedirectUri(),
|
|
scope: 'openid',
|
|
code_challenge: challenge,
|
|
code_challenge_method: 'S256',
|
|
state:
|
|
typeof crypto !== 'undefined' && 'randomUUID' in crypto
|
|
? crypto.randomUUID()
|
|
: String(Date.now()),
|
|
});
|
|
const url = `${getPublicApiOrigin()}/oauth/authorize?${params.toString()}`;
|
|
window.location.href = url;
|
|
}
|
|
|
|
export function takeStoredPkceVerifier(): string | null {
|
|
if (typeof window === 'undefined') {
|
|
return null;
|
|
}
|
|
const v = sessionStorage.getItem(VERIFIER_KEY);
|
|
if (v) {
|
|
sessionStorage.removeItem(VERIFIER_KEY);
|
|
}
|
|
return v;
|
|
}
|