mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-30 10:56:28 +02:00
* proxy: add userinfo and webauthn endpoints * use TLD for RP id * use EffectiveTLDPlusOne * upgrade webauthn * fix test * Update internal/handlers/jwks.go Co-authored-by: bobby <1544881+desimone@users.noreply.github.com> Co-authored-by: bobby <1544881+desimone@users.noreply.github.com>
90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
import React, { FC } from "react";
|
|
|
|
import { WebAuthnCreationOptions } from "../types";
|
|
import { decode, encodeUrl } from "../util/base64";
|
|
import WebAuthnButton, { WebAuthnButtonProps } from "./WebAuthnButton";
|
|
|
|
type CredentialForCreate = {
|
|
id: string;
|
|
type: string;
|
|
rawId: ArrayBuffer;
|
|
response: {
|
|
attestationObject: ArrayBuffer;
|
|
clientDataJSON: ArrayBuffer;
|
|
};
|
|
};
|
|
|
|
async function createCredential(
|
|
creationOptions: WebAuthnCreationOptions
|
|
): Promise<CredentialForCreate> {
|
|
const credential = await navigator.credentials.create({
|
|
publicKey: {
|
|
attestation: creationOptions?.attestation || undefined,
|
|
authenticatorSelection: {
|
|
authenticatorAttachment:
|
|
creationOptions?.authenticatorSelection?.authenticatorAttachment ||
|
|
undefined,
|
|
requireResidentKey:
|
|
creationOptions?.authenticatorSelection?.requireResidentKey ||
|
|
undefined,
|
|
residentKey: creationOptions?.authenticatorSelection?.residentKey,
|
|
userVerification:
|
|
creationOptions?.authenticatorSelection?.userVerification ||
|
|
undefined,
|
|
},
|
|
challenge: decode(creationOptions?.challenge),
|
|
pubKeyCredParams: creationOptions?.pubKeyCredParams?.map((p) => ({
|
|
type: p.type,
|
|
alg: p.alg,
|
|
})),
|
|
rp: {
|
|
name: creationOptions?.rp?.name,
|
|
id: creationOptions?.rp?.id,
|
|
},
|
|
timeout: creationOptions?.timeout,
|
|
user: {
|
|
id: decode(creationOptions?.user?.id),
|
|
name: creationOptions?.user?.name,
|
|
displayName: creationOptions?.user?.displayName,
|
|
},
|
|
},
|
|
});
|
|
return credential as CredentialForCreate;
|
|
}
|
|
|
|
export type WebAuthnRegisterButtonProps = Omit<
|
|
WebAuthnButtonProps,
|
|
"action" | "enable" | "onClick" | "text"
|
|
> & {
|
|
creationOptions: WebAuthnCreationOptions;
|
|
csrfToken: string;
|
|
url: string;
|
|
};
|
|
export const WebAuthnRegisterButton: FC<WebAuthnRegisterButtonProps> = ({
|
|
creationOptions,
|
|
...props
|
|
}) => {
|
|
async function register(): Promise<unknown> {
|
|
const credential = await createCredential(creationOptions);
|
|
return {
|
|
id: credential.id,
|
|
type: credential.type,
|
|
rawId: encodeUrl(credential.rawId),
|
|
response: {
|
|
attestationObject: encodeUrl(credential.response.attestationObject),
|
|
clientDataJSON: encodeUrl(credential.response.clientDataJSON),
|
|
},
|
|
};
|
|
}
|
|
|
|
return (
|
|
<WebAuthnButton
|
|
action="register"
|
|
enable={!!creationOptions}
|
|
onClick={register}
|
|
text={"Register New Device"}
|
|
{...props}
|
|
/>
|
|
);
|
|
};
|
|
export default WebAuthnRegisterButton;
|