131 lines
3.4 KiB
TypeScript
131 lines
3.4 KiB
TypeScript
export interface OneTapUrls {
|
|
apiBase: string;
|
|
frontendBase: string;
|
|
widgetUrl: string;
|
|
fedcmConfigUrl: string;
|
|
webIdentityUrl: string;
|
|
fedcmDiscoverUrl: string;
|
|
projectName: string;
|
|
}
|
|
|
|
export interface OneTapExample {
|
|
id: string;
|
|
label: string;
|
|
language: string;
|
|
code: string;
|
|
}
|
|
|
|
export function buildOneTapUrls(
|
|
apiBase: string,
|
|
frontendBase: string,
|
|
projectName = 'MVK ID'
|
|
): OneTapUrls {
|
|
const base = apiBase.replace(/\/+$/, '');
|
|
const front = frontendBase.replace(/\/+$/, '');
|
|
let webIdentityOrigin = front;
|
|
|
|
try {
|
|
webIdentityOrigin = new URL(base).origin;
|
|
} catch {
|
|
// keep frontend origin
|
|
}
|
|
|
|
return {
|
|
apiBase: base,
|
|
frontendBase: front,
|
|
widgetUrl: `${front}/sso-widget.js`,
|
|
fedcmConfigUrl: `${base}/fedcm/config.json`,
|
|
fedcmDiscoverUrl: `${base}/fedcm/discover.json`,
|
|
webIdentityUrl: `${webIdentityOrigin}/.well-known/web-identity`,
|
|
projectName
|
|
};
|
|
}
|
|
|
|
export function buildOneTapExamples(urls: OneTapUrls, clientId: string, redirectUri?: string): OneTapExample[] {
|
|
const { apiBase, frontendBase, widgetUrl, fedcmConfigUrl, webIdentityUrl, projectName } = urls;
|
|
const callbackUri = redirectUri?.trim() || 'https://app.example.com/auth/callback';
|
|
|
|
return [
|
|
{
|
|
id: 'widget-script',
|
|
label: 'Виджет (script)',
|
|
language: 'html',
|
|
code: `<script
|
|
src="${widgetUrl}"
|
|
data-client-id="${clientId}"
|
|
data-idp-url="${apiBase}"
|
|
data-idp-frontend-url="${frontendBase}"
|
|
data-provider-name="${projectName}"
|
|
data-redirect-uri="${callbackUri}"
|
|
data-on-success="handleLendryLogin"
|
|
></script>
|
|
|
|
<script>
|
|
function handleLendryLogin(payload) {
|
|
// payload.method — 'fedcm' | 'popup'
|
|
// payload.token / payload.idToken / payload.code
|
|
console.log('Вход через', payload.method, payload);
|
|
}
|
|
</script>`
|
|
},
|
|
{
|
|
id: 'sdk-manual',
|
|
label: 'SDK вручную',
|
|
language: 'javascript',
|
|
code: `<script src="${widgetUrl}" data-auto-init="false"></script>
|
|
<script>
|
|
LendryIdOneTap.init({
|
|
clientId: '${clientId}',
|
|
idpUrl: '${apiBase}',
|
|
frontendUrl: '${frontendBase}',
|
|
providerName: '${projectName}',
|
|
redirectUri: '${callbackUri}'
|
|
});
|
|
|
|
window.addEventListener('lendry-sso-onetap-success', (event) => {
|
|
console.log(event.detail);
|
|
});
|
|
</script>`
|
|
},
|
|
{
|
|
id: 'fedcm-native',
|
|
label: 'FedCM API',
|
|
language: 'javascript',
|
|
code: `const credential = await navigator.credentials.get({
|
|
identity: {
|
|
providers: [{
|
|
configURL: '${fedcmConfigUrl}',
|
|
clientId: '${clientId}'
|
|
}]
|
|
},
|
|
mediation: 'optional'
|
|
});
|
|
|
|
const idToken = credential?.token; // JWT — проверьте на backend`
|
|
},
|
|
{
|
|
id: 'postmessage',
|
|
label: 'Popup postMessage',
|
|
language: 'javascript',
|
|
code: `window.addEventListener('message', (event) => {
|
|
if (event.origin !== '${frontendBase}') return;
|
|
if (event.data?.type !== 'lendry-sso-onetap') return;
|
|
|
|
const { code, idToken, token, error } = event.data;
|
|
if (error) return console.error(error);
|
|
|
|
// code — обменяйте на POST ${apiBase}/oauth/token
|
|
// idToken / token — проверьте JWT (issuer = ${apiBase})
|
|
});`
|
|
},
|
|
{
|
|
id: 'curl-fedcm',
|
|
label: 'Диагностика (curl)',
|
|
language: 'bash',
|
|
code: `curl -sH "Sec-Fetch-Dest: webidentity" ${webIdentityUrl}
|
|
curl -sH "Sec-Fetch-Dest: webidentity" ${fedcmConfigUrl}
|
|
curl -s ${apiBase}/fedcm/discover.json`
|
|
}
|
|
];
|
|
}
|