Skip to content

Commit

Permalink
refactor: Update auth_email_passwordless and auth_email_password
Browse files Browse the repository at this point in the history
…to use the new flows proposed
  • Loading branch information
Blckbrry-Pi committed Sep 10, 2024
1 parent 8b5d6a5 commit 41ab2d9
Show file tree
Hide file tree
Showing 29 changed files with 773 additions and 496 deletions.
30 changes: 10 additions & 20 deletions modules/auth_email_password/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,16 @@
"fromName": "Authentication Code"
},
"scripts": {
"send_verification": {
"name": "Send Email Verification",
"description": "Send a one-time verification code to an email address to verify ownership.",
"public": true
},
"sign_in_email_pass": {
"name": "Sign In with Email and Password",
"description": "Sign in a user with an email and password.",
"public": true
},
"verify_sign_up_email_pass": {
"name": "Verify and Sign Up with Email and Password",
"description": "Sign up a new user with an email and password.",
"public": true
},
"verify_add_email_pass": {
"name": "Verify and Add Email and Password to existing user",
"description": "Verify a user's email address and register it with an existing account. Requires a password.",
"public": true
}
"sign_in": {
"name": "Sign In",
"description": "Initiates a verification flow with an intended action attached. Returns a token to reference that verification/action.",
"public": true
},
"verify_code": {
"name": "Verify Code",
"description": "Verifies ownership of an email and executes the intended action. May error if action is not able to be taken.",
"public": true
}
},
"errors": {
"verification_code_invalid": {
Expand Down
40 changes: 0 additions & 40 deletions modules/auth_email_password/scripts/send_verification.ts

This file was deleted.

77 changes: 77 additions & 0 deletions modules/auth_email_password/scripts/sign_in.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Empty, Module, RuntimeError, ScriptContext, UnreachableError } from "../module.gen.ts";
import { ensureNotAssociated, ensureNotAssociatedAll } from "../utils/link_assertions.ts";
import { IDENTITY_INFO_PASSWORD } from "../utils/provider.ts";

interface ConnectRequest {
connectEmail: {
userToken: string;
};
}
interface SignInRequest {
signIn: {
createUser: boolean;
};
}
interface SignUpRequest {
signUp: Empty;
}
export type Request = { email: string, password: string } & (ConnectRequest | SignInRequest | SignUpRequest);

export interface Response {
token: string;
}

const HOUR_MS = 60 * 60 * 1000;
const ATTEMPTS = 3;

export async function run(ctx: ScriptContext, req: Request): Promise<Response> {
let verificationData: unknown;
if ("connectEmail" in req) {
const { userId } = await ctx.modules.users.authenticateToken({
userToken: req.connectEmail.userToken,
});

if (await ctx.modules.userPasswords.meta({ userId })) {
await ctx.modules.userPasswords.verify({ userId, password: req.password });
await ensureNotAssociatedAll(ctx, req.email, new Set());
verificationData = { email: req.email, connect: userId, createdAt: new Date().toISOString() };
} else {
const newHash = Module.userPasswords.prehash(req.password);
verificationData = { email: req.email, newHash, connect: userId };
}
} else if ("signIn" in req) {
try {
const { userId } = await ctx.modules.identities.signIn({
info: IDENTITY_INFO_PASSWORD,
uniqueData: { identifier: req.email },
});

await ctx.modules.userPasswords.verify({ userId, password: req.password });

verificationData = { email: req.email, signIn: userId, createdAt: new Date().toISOString() };
} catch (e) {
if (!(e instanceof RuntimeError) || e.code !== "identity_provider_not_found") {
throw e;
}
if (!req.signIn.createUser) throw new RuntimeError("email_unregistered");

await ensureNotAssociatedAll(ctx, req.email, new Set());
const newHash = Module.userPasswords.prehash(req.password);
verificationData = { email: req.email, signUp: true, newHash };
}
} else if ("signUp" in req) {
await ensureNotAssociatedAll(ctx, req.email, new Set());
const newHash = Module.userPasswords.prehash(req.password);
verificationData = { email: req.email, signUp: true, newHash };
} else {
throw new UnreachableError(req);
}

const { token } = await ctx.modules.verifications.create({
data: verificationData,
expireAt: new Date(Date.now() + HOUR_MS).toISOString(),
maxAttempts: ATTEMPTS,
});

return { token };
}
35 changes: 0 additions & 35 deletions modules/auth_email_password/scripts/sign_in_email_pass.ts

This file was deleted.

85 changes: 0 additions & 85 deletions modules/auth_email_password/scripts/verify_add_email_pass.ts

This file was deleted.

Loading

0 comments on commit 41ab2d9

Please sign in to comment.