Skip to content

Commit

Permalink
Add init setup for webauthn recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
deepjyoti30-st committed Dec 19, 2024
1 parent 4e78607 commit 698eb5f
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lib/ts/recipe/webauthn/functionOverrides.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { OnHandleEventContext } from "./types";
import type { RecipeOnHandleEventFunction } from "../recipeModule/types";
import type { RecipeInterface } from "supertokens-web-js/recipe/webauthn";

export const getFunctionOverrides =
(onHandleEvent: RecipeOnHandleEventFunction<OnHandleEventContext>) =>
(originalImp: RecipeInterface): RecipeInterface => ({
...originalImp,
});
28 changes: 28 additions & 0 deletions lib/ts/recipe/webauthn/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import Webauthn from "./recipe";

import type { UserInput } from "./types";

export default class Wrapper {
static init(config: UserInput) {
return Webauthn.init(config);
}
}

const init = Wrapper.init;

export { init };
104 changes: 104 additions & 0 deletions lib/ts/recipe/webauthn/recipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import WebauthnWebJS from "supertokens-web-js/lib/build/recipe/webauthn";

import AuthRecipe from "../authRecipe";

import { getFunctionOverrides } from "./functionOverrides";
import { normaliseWebauthnConfig } from "./util";

import type {
GetRedirectionURLContext,
NormalisedConfig,
OnHandleEventContext,
PreAndPostAPIHookAction,
UserInput,
} from "./types";
import type {
NormalisedConfigWithAppInfoAndRecipeID,
WebJSRecipeInterface,
NormalisedAppInfo,
RecipeInitResult,
} from "../../types";
import type RecipeModule from "../recipeModule";

export default class Webauthn extends AuthRecipe<
GetRedirectionURLContext,
PreAndPostAPIHookAction,
OnHandleEventContext,
NormalisedConfig
> {
static instance?: Webauthn;
static RECIPE_ID = "passwordless";

recipeID = Webauthn.RECIPE_ID;
firstFactorIds = [];

constructor(
config: NormalisedConfigWithAppInfoAndRecipeID<NormalisedConfig>,
public readonly webJSRecipe: WebJSRecipeInterface<typeof WebauthnWebJS> = WebauthnWebJS
) {
super(config);
this.recipeID = config.recipeId;

// We can ideally call postInitCallbacks to set MFA's if
// we are using it.
}

public getFirstFactorsForAuthPage(): string[] {
return this.firstFactorIds;
}

getDefaultRedirectionURL = async (context: GetRedirectionURLContext): Promise<string> => {
return this.getAuthRecipeDefaultRedirectionURL(context);
};

static init(
config: UserInput
): RecipeInitResult<GetRedirectionURLContext, PreAndPostAPIHookAction, OnHandleEventContext, NormalisedConfig> {
const normalisedConfig = normaliseWebauthnConfig(config);

return {
recipeID: Webauthn.RECIPE_ID,
authReact: (
appInfo: NormalisedAppInfo
): RecipeModule<
GetRedirectionURLContext,
PreAndPostAPIHookAction,
OnHandleEventContext,
NormalisedConfig
> => {
Webauthn.instance = new Webauthn({
...normalisedConfig,
appInfo,
recipeId: Webauthn.RECIPE_ID,
});
return Webauthn.instance;
},
webJS: WebauthnWebJS.init({
...normalisedConfig,
override: {
functions: (originalImpl, builder) => {
const functions = getFunctionOverrides(normalisedConfig.onHandleEvent);
builder.override(functions);
builder.override(normalisedConfig.override.functions);
return originalImpl;
},
},
}),
};
}
}
97 changes: 97 additions & 0 deletions lib/ts/recipe/webauthn/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import type { FeatureBaseConfig, NormalisedGetRedirectionURLContext, WebJSRecipeInterface } from "../../types";
import type {
OnHandleEventContext as AuthRecipeModuleOnHandleEventContext,
UserInput as AuthRecipeModuleUserInput,
NormalisedConfig as NormalisedAuthRecipeModuleConfig,
Config as AuthRecipeModuleConfig,
} from "../authRecipe/types";
import type WebJSRecipe from "supertokens-web-js/recipe/webauthn";
import type { RecipeInterface } from "supertokens-web-js/recipe/webauthn";
import type { User } from "supertokens-web-js/types";

export type WebauthnFeatureBaseConfig = {
disableDefaultUI?: boolean;
} & FeatureBaseConfig;

export type GetRedirectionURLContext = NormalisedGetRedirectionURLContext<{
/*
* Get Redirection URL Context
*/
action: "RECOVER_ACCOUNT";
}>;

export type PreAndPostAPIHookAction =
| "REGISTER_OPTIONS"
| "SIGN_IN_OPTIONS"
| "SIGN_UP"
| "SIGN_IN"
| "EMAIL_EXISTS"
| "GENERATE_RECOVER_ACCOUNT_TOKEN"
| "RECOVER_ACCOUNT";

export type OnHandleEventContext =
| {
action: "SUCCESS";
isNewRecipeUser: boolean;
createdNewSession: boolean;
user: User;
}
| {
action: "REGISTER_CREDENTIAL";
}
| {
action: "CREDENTIAL_ADDED";
}
| {
action: "AUTHENTICATE_CREDENTIAL";
}
| {
action: "CREDENTIAL_AUTHENTICATED";
}
| {
action: "SIGN_IN";
}
| {
action: "SIGN_UP";
}
| {
action: "SEND_RECOVER_TOKEN";
}
| {
action: "RECOVER_ACCOUNT_FAILED";
}
| {
action: "RECOVER_ACCOUNT_SUCCEEDED";
}
| AuthRecipeModuleOnHandleEventContext;

export type UserInput = Record<string, unknown> & {
override?: {
functions?: (originalImplementation: RecipeInterface) => RecipeInterface;
};
linkClickedScreenFeature?: WebauthnFeatureBaseConfig;
mfaFeature?: WebauthnFeatureBaseConfig;
} & AuthRecipeModuleUserInput<GetRedirectionURLContext, PreAndPostAPIHookAction, OnHandleEventContext>;

export type Config = UserInput &
AuthRecipeModuleConfig<GetRedirectionURLContext, PreAndPostAPIHookAction, OnHandleEventContext>;

export type NormalisedConfig = Record<string, unknown> &
NormalisedAuthRecipeModuleConfig<GetRedirectionURLContext, PreAndPostAPIHookAction, OnHandleEventContext>;

export type RecipeImplementation = WebJSRecipeInterface<typeof WebJSRecipe>;
16 changes: 16 additions & 0 deletions lib/ts/recipe/webauthn/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { normaliseAuthRecipe } from "../authRecipe/utils";

import type { Config, NormalisedConfig } from "./types";
import type { RecipeInterface } from "supertokens-web-js/recipe/webauthn";

export function normaliseWebauthnConfig(config: Config): NormalisedConfig {
const override: any = {
functions: (originalImplementation: RecipeInterface) => originalImplementation,
...config.override,
};

return {
...normaliseAuthRecipe(config),
override,
};
}

0 comments on commit 698eb5f

Please sign in to comment.