Skip to content

Commit

Permalink
add web3auth email, sms passwordless login types
Browse files Browse the repository at this point in the history
  • Loading branch information
chaitanyapotti committed Aug 29, 2024
1 parent 2187a22 commit 4a27bd2
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/handlers/HandlerFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import MockLoginHandler from "./MockLoginHandler";
import PasskeysHandler from "./PasskeysHandler";
import PasswordlessHandler from "./PasswordlessHandler";
import TwitchHandler from "./TwitchHandler";
import Web3AuthPasswordlessHandler from "./Web3AuthPasswordlessHandler";

const createHandler = (params: CreateHandlerParams): ILoginHandler => {
const { verifier, typeOfLogin, clientId, jwtParams } = params;
Expand All @@ -24,6 +25,10 @@ const createHandler = (params: CreateHandlerParams): ILoginHandler => {
return new TwitchHandler(params);
case LOGIN.DISCORD:
return new DiscordHandler(params);
case LOGIN.EMAIL_PASSWORDLESS:
case LOGIN.SMS_PASSWORDLESS:
if (!login_hint) throw new Error("Invalid params. Missing login_hint for web3auth passwordless login");
return new Web3AuthPasswordlessHandler(params);
case LOGIN.PASSWORDLESS:
if (!domain || !login_hint) throw new Error("Invalid params. Missing domain or login_hint for passwordless login");
return new PasswordlessHandler(params);
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/PasswordlessHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import log from "../utils/loglevel";
import AbstractLoginHandler from "./AbstractLoginHandler";
import { Auth0UserInfo, CreateHandlerParams, LoginWindowResponse, PopupResponse, TorusVerifierResponse } from "./interfaces";

export default class JwtHandler extends AbstractLoginHandler {
export default class PasswordlessHandler extends AbstractLoginHandler {
private readonly SCOPE: string = "openid profile email";

private readonly RESPONSE_TYPE: string = "token id_token";
Expand Down
60 changes: 60 additions & 0 deletions src/handlers/Web3AuthPasswordlessHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import deepmerge from "deepmerge";

import { decodeToken, loginToConnectionMap } from "../utils/helpers";
import AbstractLoginHandler from "./AbstractLoginHandler";
import { Auth0UserInfo, CreateHandlerParams, EMAIL_FLOW, LoginWindowResponse, TorusVerifierResponse } from "./interfaces";

export default class Web3AuthPasswordlessHandler extends AbstractLoginHandler {
private readonly SCOPE: string = "openid profile email";

private readonly RESPONSE_TYPE: string = "token id_token";

private readonly PROMPT: string = "login";

constructor(params: CreateHandlerParams) {
super(params);
this.setFinalUrl();
}

setFinalUrl(): void {
const finalUrl = new URL("https://passwordless.web3auth.io/v6/authorize");
const clonedParams = JSON.parse(JSON.stringify(this.params.jwtParams || {}));
this.params.customState = { ...(this.params.customState || {}), client: this.params.web3AuthClientId };
const finalJwtParams = deepmerge(
{
state: this.state,
client_id: this.params.clientId || this.params.web3AuthClientId,
redirect_uri: this.params.redirect_uri,
nonce: this.nonce,
network: this.params.web3AuthNetwork,
connection: loginToConnectionMap[this.params.typeOfLogin],
web3auth_client_id: this.params.web3AuthClientId,
scope: this.SCOPE,
response_type: this.RESPONSE_TYPE,
prompt: this.PROMPT,
flow_type: clonedParams?.flow_type || EMAIL_FLOW.code,
},
clonedParams
);
Object.keys(finalJwtParams).forEach((key: string) => {
const localKey = key as keyof typeof finalJwtParams;
if (finalJwtParams[localKey]) finalUrl.searchParams.append(localKey, finalJwtParams[localKey]);
});
this.finalURL = finalUrl;
}

async getUserInfo(params: LoginWindowResponse): Promise<TorusVerifierResponse> {
const { idToken } = params;

const decodedToken = decodeToken<Auth0UserInfo>(idToken).payload;
const { name, email, picture } = decodedToken;
return {
profileImage: picture,
name,
email,
verifierId: name.toLowerCase(),
verifier: this.params.verifier,
typeOfLogin: this.params.typeOfLogin,
};
}
}
14 changes: 14 additions & 0 deletions src/handlers/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,13 @@ export interface BaseLoginOptions {
connection?: string;
}

export const EMAIL_FLOW = {
link: "link",
code: "code",
} as const;

export type EMAIL_FLOW_TYPE = (typeof EMAIL_FLOW)[keyof typeof EMAIL_FLOW];

export interface Auth0ClientOptions extends BaseLoginOptions {
/**
* Your Auth0 account domain such as `'example.auth0.com'`,
Expand Down Expand Up @@ -363,6 +370,11 @@ export interface Auth0ClientOptions extends BaseLoginOptions {
* @defaultValue userinfo
* */
user_info_route?: string;

/**
* The flow type for email_passwordless login
*/
flow_type?: EMAIL_FLOW_TYPE;
}

export interface SubVerifierDetails {
Expand All @@ -384,6 +396,8 @@ export interface CreateHandlerParams {
redirectToOpener?: boolean;
jwtParams?: Auth0ClientOptions;
customState?: TorusGenericObject;
web3AuthClientId: string;
web3AuthNetwork: TORUS_NETWORK_TYPE;
}

export interface RedirectResultParams {
Expand Down
9 changes: 9 additions & 0 deletions src/login.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TORUS_NETWORK_TYPE } from "@toruslabs/constants";
import { NodeDetailManager } from "@toruslabs/fetch-node-details";
import { keccak256, Torus, TorusKey } from "@toruslabs/torus.js";

Expand Down Expand Up @@ -37,6 +38,8 @@ class CustomAuth {
uxMode: UX_MODE_TYPE;
locationReplaceOnRedirect: boolean;
popupFeatures: string;
web3AuthClientId: string;
web3AuthNetwork: TORUS_NETWORK_TYPE;
};

torus: Torus;
Expand Down Expand Up @@ -77,6 +80,8 @@ class CustomAuth {
uxMode,
locationReplaceOnRedirect,
popupFeatures,
web3AuthClientId,
web3AuthNetwork: network,
};
const torus = new Torus({
network,
Expand Down Expand Up @@ -141,6 +146,8 @@ class CustomAuth {
jwtParams,
uxMode: this.config.uxMode,
customState,
web3AuthClientId: this.config.web3AuthClientId,
web3AuthNetwork: this.config.web3AuthNetwork,
});
let loginParams: LoginWindowResponse;
if (hash && queryParameters) {
Expand Down Expand Up @@ -204,6 +211,8 @@ class CustomAuth {
jwtParams,
uxMode: this.config.uxMode,
customState,
web3AuthClientId: this.config.web3AuthClientId,
web3AuthNetwork: this.config.web3AuthNetwork,
});
// We let the user login to each verifier in a loop. Don't wait for key derivation here.!
let loginParams: LoginWindowResponse;
Expand Down
2 changes: 2 additions & 0 deletions src/utils/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export const LOGIN = {
LINE: "line",
EMAIL_PASSWORD: "email_password",
PASSWORDLESS: "passwordless",
EMAIL_PASSWORDLESS: "email_passwordless",
SMS_PASSWORDLESS: "sms_passwordless",
JWT: "jwt",
PASSKEYS: "passkeys",
} as const;
Expand Down
6 changes: 5 additions & 1 deletion src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function eventToPromise<T>(emitter: EmitterType): Promise<T> {
}

// These are the default connection names used by auth0
export const loginToConnectionMap = {
export const loginToConnectionMap: Record<string, string> = {
[LOGIN.APPLE]: "apple",
[LOGIN.GITHUB]: "github",
[LOGIN.LINKEDIN]: "linkedin",
Expand All @@ -36,6 +36,8 @@ export const loginToConnectionMap = {
[LOGIN.LINE]: "line",
[LOGIN.EMAIL_PASSWORD]: "Username-Password-Authentication",
[LOGIN.PASSWORDLESS]: "email",
[LOGIN.EMAIL_PASSWORDLESS]: "email",
[LOGIN.SMS_PASSWORDLESS]: "sms",
};

export const padUrlString = (url: URL): string => (url.href.endsWith("/") ? url.href : `${url.href}/`);
Expand Down Expand Up @@ -66,6 +68,8 @@ export const getVerifierId = (
switch (typeOfLogin) {
case LOGIN.PASSWORDLESS:
case LOGIN.EMAIL_PASSWORD:
case LOGIN.EMAIL_PASSWORDLESS:
case LOGIN.SMS_PASSWORDLESS:
return caseSensitiveField(name, isVerifierIdCaseSensitive);
case LOGIN.WEIBO:
case LOGIN.GITHUB:
Expand Down

0 comments on commit 4a27bd2

Please sign in to comment.