@syncello/auth 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -4109,7 +4109,7 @@ var resetPasswordRoute = (0, import_zod_openapi8.createRoute)({
4109
4109
  });
4110
4110
  var resetPasswordHandler = async (c) => {
4111
4111
  const { token, password, turnstileToken } = c.req.valid("json");
4112
- const database = c.get("db");
4112
+ const { db: database, schema } = getAuthContext(c);
4113
4113
  const env = c.env;
4114
4114
  const turnstileValid = await verifyTurnstileToken(
4115
4115
  turnstileToken,
@@ -4124,7 +4124,18 @@ var resetPasswordHandler = async (c) => {
4124
4124
  if (!passwordValidation.valid) {
4125
4125
  return problems.badRequest(c, passwordValidation.error || "Invalid password");
4126
4126
  }
4127
- const result = await resetPassword(database, token, password, env.PASSWORD_PEPPER_V1, "v1");
4127
+ const result = await resetPassword(
4128
+ database,
4129
+ {
4130
+ users: schema.users,
4131
+ passwordResetTokens: schema.passwordResetTokens,
4132
+ sessions: schema.sessions
4133
+ },
4134
+ token,
4135
+ password,
4136
+ env.PASSWORD_PEPPER_V1,
4137
+ "v1"
4138
+ );
4128
4139
  if (!result.success) {
4129
4140
  return problems.badRequest(c, result.error || "Invalid or expired reset token");
4130
4141
  }
@@ -5727,9 +5738,10 @@ var PROVIDERS = {
5727
5738
  authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
5728
5739
  tokenUrl: "https://oauth2.googleapis.com/token",
5729
5740
  userinfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo",
5730
- scopes: ["email"],
5741
+ scopes: ["email", "profile"],
5731
5742
  emailExtractor: (data) => data.email || null,
5732
- userIdExtractor: (data) => data.id || null
5743
+ userIdExtractor: (data) => data.id || null,
5744
+ nameExtractor: (data) => data.name || null
5733
5745
  },
5734
5746
  microsoft: {
5735
5747
  authorizeUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
@@ -5737,7 +5749,8 @@ var PROVIDERS = {
5737
5749
  userinfoUrl: "https://graph.microsoft.com/v1.0/me",
5738
5750
  scopes: ["openid", "email", "User.Read"],
5739
5751
  emailExtractor: (data) => data.mail || data.userPrincipalName || null,
5740
- userIdExtractor: (data) => data.id || null
5752
+ userIdExtractor: (data) => data.id || null,
5753
+ nameExtractor: (data) => data.displayName || null
5741
5754
  }
5742
5755
  };
5743
5756
  function getProviderCredentials(provider, env) {
@@ -5974,6 +5987,7 @@ var callbackHandler = async (c) => {
5974
5987
  const userInfo = await userinfoResponse.json();
5975
5988
  const email = providerConfig.emailExtractor(userInfo)?.toLowerCase();
5976
5989
  const providerUserId = providerConfig.userIdExtractor(userInfo);
5990
+ const name = providerConfig.nameExtractor(userInfo);
5977
5991
  if (!email) {
5978
5992
  logger_default.warn("No email returned from OAuth provider", { provider });
5979
5993
  return c.redirect(`${appUrl}/login?error=oauth_no_email`);
@@ -5984,53 +5998,49 @@ var callbackHandler = async (c) => {
5984
5998
  }
5985
5999
  const { db, schema } = getAuthContext(c);
5986
6000
  const [existingUser] = await db.select({ id: schema.users.id, email: schema.users.email }).from(schema.users).where((0, import_drizzle_orm32.eq)(schema.users.email, email)).limit(1);
5987
- if (existingUser) {
5988
- const loginCode = crypto.randomUUID();
5989
- await c.env.OAUTH_STATES.put(
5990
- `oauth:login:${loginCode}`,
5991
- JSON.stringify({
5992
- userId: existingUser.id,
5993
- email: existingUser.email,
5994
- provider,
5995
- providerUserId,
5996
- redirect: loginRedirect,
5997
- invitationToken
5998
- }),
5999
- { expirationTtl: 60 }
6000
- );
6001
- logSecurityEvent("oauth_login_initiated", "low", {
6002
- userId: existingUser.id,
6003
- email: existingUser.email,
6001
+ let authUser = existingUser;
6002
+ if (!authUser) {
6003
+ const [createdUser] = await db.insert(schema.users).values({
6004
+ email,
6005
+ name: name || null,
6006
+ hashedPassword: null,
6007
+ pepperKid: null,
6008
+ emailVerified: true,
6009
+ // Provider verified the email
6010
+ activatedAt: /* @__PURE__ */ new Date()
6011
+ }).returning({ id: schema.users.id, email: schema.users.email });
6012
+ authUser = createdUser;
6013
+ logSecurityEvent("user_signup_oauth", "low", {
6014
+ userId: createdUser.id,
6015
+ email: createdUser.email,
6004
6016
  provider
6005
6017
  });
6006
- if (mobileRedirectUri && isDeepLinkUri(mobileRedirectUri)) {
6007
- const mobileUrl = new URL(mobileRedirectUri);
6008
- mobileUrl.searchParams.set("code", loginCode);
6009
- mobileUrl.searchParams.set("action", "login");
6010
- return c.redirect(mobileUrl.toString());
6011
- }
6012
- return c.redirect(`${appUrl}/auth/callback?code=${loginCode}&action=login`);
6013
- } else {
6014
- const signupToken = crypto.randomUUID();
6015
- await c.env.OAUTH_STATES.put(
6016
- `oauth:signup:${signupToken}`,
6017
- JSON.stringify({ email, provider, providerUserId, invitationToken }),
6018
- { expirationTtl: 600 }
6019
- );
6020
- logger_default.info("OAuth signup initiated", { provider, email });
6021
- if (mobileRedirectUri && isDeepLinkUri(mobileRedirectUri)) {
6022
- const mobileUrl = new URL(mobileRedirectUri);
6023
- mobileUrl.searchParams.set("oauth_token", signupToken);
6024
- mobileUrl.searchParams.set("email", email);
6025
- if (invitationToken) {
6026
- mobileUrl.searchParams.set("invitation", invitationToken);
6027
- }
6028
- return c.redirect(mobileUrl.toString());
6029
- }
6030
- let signupUrl = `${appUrl}/signup?oauth_token=${signupToken}&email=${encodeURIComponent(email)}`;
6031
- if (invitationToken) signupUrl += `&invitation=${invitationToken}`;
6032
- return c.redirect(signupUrl);
6033
6018
  }
6019
+ const loginCode = crypto.randomUUID();
6020
+ await c.env.OAUTH_STATES.put(
6021
+ `oauth:login:${loginCode}`,
6022
+ JSON.stringify({
6023
+ userId: authUser.id,
6024
+ email: authUser.email,
6025
+ provider,
6026
+ providerUserId,
6027
+ redirect: loginRedirect,
6028
+ invitationToken
6029
+ }),
6030
+ { expirationTtl: 60 }
6031
+ );
6032
+ logSecurityEvent("oauth_login_initiated", "low", {
6033
+ userId: authUser.id,
6034
+ email: authUser.email,
6035
+ provider
6036
+ });
6037
+ if (mobileRedirectUri && isDeepLinkUri(mobileRedirectUri)) {
6038
+ const mobileUrl = new URL(mobileRedirectUri);
6039
+ mobileUrl.searchParams.set("code", loginCode);
6040
+ mobileUrl.searchParams.set("action", "login");
6041
+ return c.redirect(mobileUrl.toString());
6042
+ }
6043
+ return c.redirect(`${appUrl}/auth/callback?code=${loginCode}&action=login`);
6034
6044
  } catch (err) {
6035
6045
  logError(err, { context: "oauth_callback", provider });
6036
6046
  return c.redirect(`${appUrl}/login?error=oauth_failed`);