Skip to content
This repository was archived by the owner on Sep 17, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading