Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: anomaly and security service integration #855

Draft
wants to merge 24 commits into
base: 20.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5eb92f2
types changes for ep recipe interface (code not compiling)
rishabhpoddar Jun 11, 2024
7020829
Merge branch '19.0' into feat/anomaly-service-integration
rishabhpoddar Jun 11, 2024
dabae70
more changes
rishabhpoddar Jun 11, 2024
b2e2330
Merge branch 'feat/anomaly-service-integration' of https://github.com…
rishabhpoddar Jun 11, 2024
08d1613
Merge branch '19.0' into feat/anomaly-service-integration
rishabhpoddar Jun 28, 2024
26b9ae8
modifes types of emailpassword recipe
rishabhpoddar Jul 1, 2024
51ff02b
Merge branch '19.0' into feat/anomaly-service-integration
rishabhpoddar Jul 1, 2024
d1691e1
adds types for all the override functions
rishabhpoddar Jul 1, 2024
40c114b
makes rate limiting an array of keys
rishabhpoddar Jul 1, 2024
9eafc55
adds more type changes
rishabhpoddar Jul 1, 2024
88da59b
more type changes
rishabhpoddar Jul 2, 2024
a8ae033
Merge branch '19.0' into feat/anomaly-service-integration
rishabhpoddar Jul 16, 2024
6d33e18
fixes a few comments
rishabhpoddar Jul 16, 2024
239e2de
resolves all pr comments
rishabhpoddar Jul 16, 2024
14a1963
Merge branch '19.0' into feat/anomaly-service-integration
rishabhpoddar Jul 16, 2024
2067006
more changes
rishabhpoddar Jul 16, 2024
ab0baa0
Merge branch 'feat/anomaly-service-integration' of https://github.com…
rishabhpoddar Jul 16, 2024
8aca4cf
Merge branch '19.0' into feat/anomaly-service-integration
rishabhpoddar Jul 16, 2024
402726d
small changes
rishabhpoddar Jul 16, 2024
91de44c
Merge branch 'feat/anomaly-service-integration' of https://github.com…
rishabhpoddar Jul 16, 2024
cf3d581
removes google recaptcha and security service request id from totp
rishabhpoddar Jul 16, 2024
2b6e09e
adds a few more params from security service
rishabhpoddar Jul 17, 2024
77a3dde
Merge branch '20.0' into feat/anomaly-service-integration
rishabhpoddar Jul 26, 2024
b19c86f
changes output schema of api
rishabhpoddar Jul 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 105 additions & 3 deletions lib/ts/recipe/emailpassword/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ export type RecipeInterface = {
password: string;
session: SessionContainerInterface | undefined;
tenantId: string;
securityOptions?: {
enforceEmailBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
};
userContext: UserContext;
}): Promise<
| {
Expand All @@ -105,6 +110,14 @@ export type RecipeInterface = {
| "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
| "SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR";
}
| {
status: "EMAIL_BANNED_ERROR" | "IP_BANNED_ERROR";
}
| {
// this can happen during account linking, if the primary user that this is going to be linked to is banned.
status: "USER_BANNED_ERROR";
user: User;
}
>;
// this function is meant only for creating the recipe in the core and nothing else.
// we added this even though signUp exists cause devs may override signup expecting it
Expand All @@ -114,6 +127,11 @@ export type RecipeInterface = {
email: string;
password: string;
tenantId: string;
securityOptions?: {
enforceEmailBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
};
userContext: UserContext;
}): Promise<
| {
Expand All @@ -122,17 +140,32 @@ export type RecipeInterface = {
recipeUserId: RecipeUserId;
}
| { status: "EMAIL_ALREADY_EXISTS_ERROR" }
| {
status: "EMAIL_BANNED_ERROR" | "IP_BANNED_ERROR";
}
>;

signIn(input: {
email: string;
password: string;
session: SessionContainerInterface | undefined;
tenantId: string;
securityOptions?: {
enforceUserBan?: boolean;
enforceEmailBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
limitWrongCredentialsAttempt?: {
enabled?: boolean;
counterKey?: string; // by default, it is just email ID
maxNumberOfIncorrectAttempts?: number; // by default, it is 4
lockoutTimeInSeconds?: number; // by default, it is 60
};
};
userContext: UserContext;
}): Promise<
| { status: "OK"; user: User; recipeUserId: RecipeUserId }
| { status: "WRONG_CREDENTIALS_ERROR" }
| { status: "WRONG_CREDENTIALS_ERROR"; numberOfIncorrectAttemptsSoFar: number }
| {
status: "LINKING_TO_SESSION_USER_FAILED";
reason:
Expand All @@ -141,14 +174,53 @@ export type RecipeInterface = {
| "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
| "SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR";
}
| {
status: "EMAIL_BANNED_ERROR" | "IP_BANNED_ERROR";
}
| {
status: "USER_BANNED_ERROR";
user: User;
recipeUserId: RecipeUserId;
}
| {
status: "WRONG_CREDENTIALS_LIMIT_REACHED_ERROR";
remainingLockingTimeInSeconds: number;
}
>;

verifyCredentials(input: {
email: string;
password: string;
tenantId: string;
userContext: UserContext;
}): Promise<{ status: "OK"; user: User; recipeUserId: RecipeUserId } | { status: "WRONG_CREDENTIALS_ERROR" }>;
securityOptions?: {
enforceUserBan?: boolean;
enforceEmailBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
limitWrongCredentialsAttempt?: {
enabled?: boolean;
counterKey?: string; // by default, it is just email ID
maxNumberOfIncorrectAttempts?: number; // by default, it is 4
lockoutTimeInSeconds?: number; // by default, it is 60
};
};
}): Promise<
| { status: "OK"; user: User; recipeUserId: RecipeUserId }
| { status: "WRONG_CREDENTIALS_ERROR" }
| {
status: "EMAIL_BANNED_ERROR" | "IP_BANNED_ERROR";
}
| {
status: "USER_BANNED_ERROR";
user: User;
recipeUserId: RecipeUserId;
}
| {
status: "WRONG_CREDENTIALS_LIMIT_REACHED_ERROR";
remainingLockingTimeInSeconds: number;
}
>;

/**
* We pass in the email as well to this function cause the input userId
Expand All @@ -159,8 +231,25 @@ export type RecipeInterface = {
userId: string; // the id can be either recipeUserId or primaryUserId
email: string;
tenantId: string;
securityOptions?: {
enforceUserBan?: boolean;
enforceEmailBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
};
userContext: UserContext;
}): Promise<{ status: "OK"; token: string } | { status: "UNKNOWN_USER_ID_ERROR" }>;
}): Promise<
| { status: "OK"; token: string }
| { status: "UNKNOWN_USER_ID_ERROR" }
| {
status: "EMAIL_BANNED_ERROR" | "IP_BANNED_ERROR";
}
| {
status: "USER_BANNED_ERROR";
user: User;
recipeUserId: RecipeUserId;
}
>;

consumePasswordResetToken(input: {
token: string;
Expand All @@ -183,6 +272,12 @@ export type RecipeInterface = {
password?: string;
userContext: UserContext;
applyPasswordPolicy?: boolean;
securityOptions?: {
limitOldPasswordReuse?: {
enabled?: boolean;
numberOfOldPasswordsToCheck?: number;
};
};
tenantIdForPasswordPolicy: string;
}): Promise<
| {
Expand All @@ -193,6 +288,7 @@ export type RecipeInterface = {
reason: string;
}
| { status: "PASSWORD_POLICY_VIOLATED_ERROR"; failureReason: string }
| { status: "OLD_PASSWORD_REUSED_ERROR" }
>;
};

Expand Down Expand Up @@ -226,6 +322,8 @@ export type APIInterface = {
generatePasswordResetTokenPOST:
| undefined
| ((input: {
googleRecaptchaToken?: string;
securityServiceRequestId?: string;
formFields: {
id: string;
value: string;
Expand Down Expand Up @@ -271,6 +369,8 @@ export type APIInterface = {
signInPOST:
| undefined
| ((input: {
googleRecaptchaToken?: string;
securityServiceRequestId?: string;
formFields: {
id: string;
value: string;
Expand Down Expand Up @@ -298,6 +398,8 @@ export type APIInterface = {
signUpPOST:
| undefined
| ((input: {
googleRecaptchaToken?: string;
securityServiceRequestId?: string;
formFields: {
id: string;
value: string;
Expand Down
2 changes: 2 additions & 0 deletions lib/ts/recipe/multifactorauth/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { SessionContainerInterface } from "../session/types";
import Recipe from "./recipe";
import { TenantConfig } from "../multitenancy/types";
import RecipeUserId from "../../recipeUserId";
import { RiskScores } from "../../types";

export type MFARequirementList = (
| {
Expand Down Expand Up @@ -80,6 +81,7 @@ export type RecipeInterface = {
requiredSecondaryFactorsForUser: Promise<string[]>;
requiredSecondaryFactorsForTenant: Promise<string[]>;
userContext: UserContext;
riskScores?: RiskScores;
}) => Promise<MFARequirementList> | MFARequirementList;

markFactorAsCompleteInSession: (input: {
Expand Down
73 changes: 63 additions & 10 deletions lib/ts/recipe/passwordless/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,23 +121,46 @@ export type RecipeInterface = {
session: SessionContainerInterface | undefined;
tenantId: string;
userContext: UserContext;
securityOptions?: {
enforceUserBan?: boolean; // in case this is a sign in and not a sign up
enforceEmailBan?: boolean;
rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved
enforcePhoneNumberBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
};
}
) => Promise<{
status: "OK";
preAuthSessionId: string;
codeId: string;
deviceId: string;
userInputCode: string;
linkCode: string;
codeLifetime: number;
timeCreated: number;
}>;
) => Promise<
| {
status: "OK";
preAuthSessionId: string;
codeId: string;
deviceId: string;
userInputCode: string;
linkCode: string;
codeLifetime: number;
timeCreated: number;
}
| {
status: "EMAIL_BANNED_ERROR" | "PHONE_NUMBER_BANNED" | "IP_BANNED_ERROR";
}
| {
status: "USER_BANNED_ERROR";
user: User;
recipeUserId: RecipeUserId;
}
>;

createNewCodeForDevice: (input: {
deviceId: string;
userInputCode?: string;
tenantId: string;
userContext: UserContext;
securityOptions?: {
enforceEmailBan?: boolean;
enforcePhoneNumberBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
};
}) => Promise<
| {
status: "OK";
Expand All @@ -150,6 +173,9 @@ export type RecipeInterface = {
timeCreated: number;
}
| { status: "RESTART_FLOW_ERROR" | "USER_INPUT_CODE_ALREADY_USED_ERROR" }
| {
status: "EMAIL_BANNED_ERROR" | "PHONE_NUMBER_BANNED" | "IP_BANNED_ERROR";
}
>;
consumeCode: (
input:
Expand All @@ -160,13 +186,27 @@ export type RecipeInterface = {
session: SessionContainerInterface | undefined;
tenantId: string;
userContext: UserContext;
securityOptions?: {
enforceUserBan?: boolean;
enforceEmailBan?: boolean;
enforcePhoneNumberBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
};
}
| {
linkCode: string;
preAuthSessionId: string;
session: SessionContainerInterface | undefined;
tenantId: string;
userContext: UserContext;
securityOptions?: {
enforceUserBan?: boolean;
enforceEmailBan?: boolean;
enforcePhoneNumberBan?: boolean;
enforceIpBan?: boolean;
ipAddress?: string;
};
}
) => Promise<
| {
Expand Down Expand Up @@ -195,6 +235,14 @@ export type RecipeInterface = {
| "ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR"
| "SESSION_USER_ACCOUNT_INFO_ALREADY_ASSOCIATED_WITH_ANOTHER_PRIMARY_USER_ID_ERROR";
}
| {
status: "EMAIL_BANNED_ERROR" | "PHONE_NUMBER_BANNED" | "IP_BANNED_ERROR";
}
| {
status: "USER_BANNED_ERROR";
user: User;
recipeUserId: RecipeUserId;
}
>;

checkCode: (
Expand Down Expand Up @@ -336,6 +384,8 @@ export type APIInterface = {
session: SessionContainerInterface | undefined;
rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved
options: APIOptions;
userContext: UserContext;
googleRecaptchaToken?: string;
securityServiceRequestId?: string;
}
) => Promise<
| {
Expand All @@ -351,6 +401,9 @@ export type APIInterface = {
| GeneralErrorResponse
>;

// we intentionally do not add googleRecaptcha or securityServiceRequestId in here cause
// it's the same device that generates the code during createCode, and if
// that's not a bot, nor is this.
resendCodePOST?: (
input: { deviceId: string; preAuthSessionId: string } & {
tenantId: string;
Expand Down
Loading
Loading