Skip to content

Commit

Permalink
feat: add (partial) initial types for MFA
Browse files Browse the repository at this point in the history
  • Loading branch information
porcellus committed Oct 3, 2023
1 parent 6d93571 commit 0942361
Show file tree
Hide file tree
Showing 10 changed files with 542 additions and 0 deletions.
91 changes: 91 additions & 0 deletions lib/ts/recipe/multifactorauth/api/emailVerify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* 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 { send200Response, normaliseHttpMethod } from "../../../utils";
import STError from "../error";
import { APIInterface, APIOptions } from "../";
import Session from "../../session";

export default async function emailVerify(
apiImplementation: APIInterface,
tenantId: string,
options: APIOptions,
userContext: any
): Promise<boolean> {
let result;

if (normaliseHttpMethod(options.req.getMethod()) === "post") {
// Logic according to Logic as per https://github.com/supertokens/supertokens-node/issues/62#issuecomment-751616106

if (apiImplementation.loginMethodsGET === undefined) {
return false;
}

let token = (await options.req.getJSONBody()).token;
if (token === undefined || token === null) {
throw new STError({
type: STError.BAD_INPUT_ERROR,
message: "Please provide the email verification token",
});
}
if (typeof token !== "string") {
throw new STError({
type: STError.BAD_INPUT_ERROR,
message: "The email verification token must be a string",
});
}

const session = await Session.getSession(
options.req,
options.res,
{ overrideGlobalClaimValidators: () => [], sessionRequired: false },
userContext
);

let response = await apiImplementation.verifyEmailPOST({
token,
tenantId,
options,
session,
userContext,
});
if (response.status === "OK") {
// if there is a new session, it will be
// automatically added to the response by the createNewSession function call
// inside the verifyEmailPOST function.
result = { status: "OK" };
} else {
result = response;
}
} else {
if (apiImplementation.isEmailVerifiedGET === undefined) {
return false;
}

const session = await Session.getSession(
options.req,
options.res,
{ overrideGlobalClaimValidators: () => [] },
userContext
);
result = await apiImplementation.isEmailVerifiedGET({
options,
session,
userContext,
});
}
send200Response(options.res, result);
return true;
}
5 changes: 5 additions & 0 deletions lib/ts/recipe/multifactorauth/api/implementation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { APIInterface } from "../";

export default function getAPIInterface(): APIInterface {
return {} as any;
}
16 changes: 16 additions & 0 deletions lib/ts/recipe/multifactorauth/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* 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.
*/

export const GET_MFA_INFO = "/mfa-info";
25 changes: 25 additions & 0 deletions lib/ts/recipe/multifactorauth/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* 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 STError from "../../error";

export default class SessionError extends STError {
constructor(options: { type: "BAD_INPUT_ERROR"; message: string }) {
super({
...options,
});
this.fromRecipe = "multifactorauth";
}
}
52 changes: 52 additions & 0 deletions lib/ts/recipe/multifactorauth/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* 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 Recipe from "./recipe";
import { RecipeInterface, APIOptions, APIInterface } from "./types";
import { ProviderConfig } from "../thirdparty/types";
import { AllowedDomainsClaim } from "./multiFactorAuthClaim";
import RecipeUserId from "../../recipeUserId";

export default class Wrapper {
static init = Recipe.init;

static async createOrUpdateTenant(
tenantId: string,
config?: {
emailPasswordEnabled?: boolean;
passwordlessEnabled?: boolean;
thirdPartyEnabled?: boolean;
coreConfig?: { [key: string]: any };
},
userContext?: any
): Promise<{
status: "OK";
createdNew: boolean;
}> {
const recipeInstance = Recipe.getInstanceOrThrowError();
return recipeInstance.recipeInterfaceImpl.createOrUpdateTenant({
tenantId,
config,
userContext: userContext === undefined ? {} : userContext,
});
}
}

export let init = Wrapper.init;

export let createOrUpdateTenant = Wrapper.createOrUpdateTenant;

export { AllowedDomainsClaim };
export type { RecipeInterface, APIOptions, APIInterface };
53 changes: 53 additions & 0 deletions lib/ts/recipe/multifactorauth/multiFactorAuthClaim.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import RecipeUserId from "../../recipeUserId";
import { SessionClaim } from "../session/claims";
import { JSONObject } from "../usermetadata";
import Recipe from "./recipe";
import { MFAClaimValue } from "./types";

/**
* We include "Class" in the class name, because it makes it easier to import the right thing (the instance) instead of this.
* */
export class MultiFactorAuthClaimClass extends SessionClaim<MFAClaimValue> {
public key = "st-mfa";

public fetchValue = (userId: string, recipeUserId: RecipeUserId, tenantId: string | undefined, userContext: any) => {

return {
c: {},
n: [],
}
}

public addToPayload_internal = (payload: JSONObject, value: MFAClaimValue) => {
const prevValue = payload[this.key] as MFAClaimValue | undefined;
return {
...payload,
[this.key]: {
c: {
...prevValue?.c,
...value.c,
},
n: value.n,
}
}
}

public removeFromPayload = (payload: JSONObject) => {
const retVal = {
...payload,
}
delete retVal[this.key];

return retVal;
}

public removeFromPayloadByMerge_internal = () => {
return {
[this.key] : null,
}
}

public getValueFromPayload = (payload: JSONObject) => {
return payload[this.key] as MFAClaimValue;
}
}
Loading

0 comments on commit 0942361

Please sign in to comment.