@upbond/customauth
Version:
CustomAuth login with torus to get user private key
126 lines (117 loc) • 3.85 kB
text/typescript
import { get } from "@toruslabs/http-helpers";
import deepmerge from "lodash.merge";
import { LOGIN_TYPE, UX_MODE_TYPE } from "../utils/enums";
import log from "../utils/loglevel";
import AbstractLoginHandler from "./AbstractLoginHandler";
import { Auth0ClientOptions, LoginWindowResponse, TorusGenericObject, TorusVerifierResponse, WebAuthnExtraParams } from "./interfaces";
const WEBAUTHN_LOOKUP_SERVER = "https://api.webauthn.openlogin.com";
export default class WebAuthnHandler extends AbstractLoginHandler {
constructor(
readonly clientId: string,
readonly verifier: string,
readonly redirect_uri: string,
readonly typeOfLogin: LOGIN_TYPE,
readonly uxMode: UX_MODE_TYPE,
readonly redirectToOpener?: boolean,
readonly jwtParams?: Auth0ClientOptions,
readonly customState?: TorusGenericObject,
readonly registerOnly?: boolean
) {
super(clientId, verifier, redirect_uri, typeOfLogin, uxMode, redirectToOpener, jwtParams, customState);
this.setFinalUrl();
}
setFinalUrl(): void {
const finalUrl = new URL("https://webauthn.openlogin.com");
const clonedParams = JSON.parse(JSON.stringify(this.jwtParams || {}));
const finalJwtParams = deepmerge(
{
register_only: !!this.registerOnly,
state: this.state,
client_id: this.clientId,
redirect_uri: this.redirect_uri,
},
clonedParams
);
Object.keys(finalJwtParams).forEach((key) => {
if (finalJwtParams[key]) finalUrl.searchParams.append(key, finalJwtParams[key]);
});
this.finalURL = finalUrl;
}
async getUserInfo(parameters: LoginWindowResponse): Promise<TorusVerifierResponse> {
const { idToken, ref, extraParamsPassed, extraParams } = parameters;
let verifierId: string;
let signature: string;
let clientDataJSON: string;
let authenticatorData: string;
let publicKey: string;
let challenge: string;
let rpOrigin: string;
let credId: string;
let transports: AuthenticatorTransport[];
if (extraParamsPassed === "true") {
log.debug("extraParamsPassed is true, using extraParams passed through hashParams");
try {
({
verifier_id: verifierId,
signature,
clientDataJSON,
authenticatorData,
publicKey,
challenge,
rpOrigin,
credId,
transports,
} = JSON.parse(atob(extraParams)));
} catch (error) {
log.warn("unable to parse extraParams", error);
({
verifier_id: verifierId,
signature,
clientDataJSON,
authenticatorData,
publicKey,
challenge,
rpOrigin,
credId,
transports,
} = await get<WebAuthnExtraParams & { verifier_id: string }>(`${WEBAUTHN_LOOKUP_SERVER}/signature/fetch/${idToken}`));
}
} else {
log.debug("extraParamsPassed is false, using extraParams passed through bridge server");
({
verifier_id: verifierId,
signature,
clientDataJSON,
authenticatorData,
publicKey,
challenge,
rpOrigin,
credId,
transports,
} = await get<WebAuthnExtraParams & { verifier_id: string }>(`${WEBAUTHN_LOOKUP_SERVER}/signature/fetch/${idToken}`));
}
if (signature !== idToken) {
throw new Error("idtoken should be equal to signature");
}
return {
email: "",
name: "WebAuthn Login",
profileImage: "",
verifier: this.verifier,
verifierId,
typeOfLogin: this.typeOfLogin,
ref,
registerOnly: this.registerOnly,
extraVerifierParams: {
signature,
clientDataJSON,
authenticatorData,
publicKey,
challenge,
rpOrigin,
credId,
transports,
},
};
}
}