@rpcbase/auth 0.45.0 → 0.47.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/api/sign-in/handler.d.ts.map +1 -1
- package/dist/api/sign-in/index.d.ts +1 -1
- package/dist/api/sign-in/index.d.ts.map +1 -1
- package/dist/api/sign-up/handler.d.ts.map +1 -1
- package/dist/api/sign-up/index.d.ts +1 -2
- package/dist/api/sign-up/index.d.ts.map +1 -1
- package/dist/api/verify-otp/handler.d.ts +5 -0
- package/dist/api/verify-otp/handler.d.ts.map +1 -0
- package/dist/api/verify-otp/index.d.ts +16 -0
- package/dist/api/verify-otp/index.d.ts.map +1 -0
- package/dist/components/{EmailOrPhoneInput → EmailInput}/index.d.ts +1 -1
- package/dist/components/EmailInput/index.d.ts.map +1 -0
- package/dist/components/PasswordInput/index.d.ts.map +1 -1
- package/dist/components/SignUpForm/index.d.ts +2 -1
- package/dist/components/SignUpForm/index.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/handler-CE4lXc0G.js +64 -0
- package/dist/handler-DOnLMd-9.js +57 -0
- package/dist/{handler-BSoyBLZM.js → handler-r4ZECW_z.js} +3 -5
- package/dist/{index-r56vqjph.js → index-Bdcryyvv.js} +1 -9
- package/dist/index-DwX0Y2YV.js +17 -0
- package/dist/index.js +98 -26
- package/dist/routes.js +1 -1
- package/package.json +8 -1
- package/dist/components/EmailOrPhoneInput/index.d.ts.map +0 -1
- package/dist/handler-rZR_dx7n.js +0 -71
- package/dist/index-Cq04nmsE.js +0 -29
- package/dist/isEmail-IG0hXiQk.js +0 -390
- package/dist/isValidNumber-6pMDGLRn.js +0 -1902
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/sign-in/handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/sign-in/handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAA8B,MAAM,cAAc,CAAA;AAG9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBA4DlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAEC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from '../../../../vite/node_modules/zod';
|
|
2
2
|
export declare const Route = "/api/rb/auth/sign-in";
|
|
3
3
|
export declare const requestSchema: z.ZodObject<{
|
|
4
|
-
|
|
4
|
+
email: z.ZodString;
|
|
5
5
|
password: z.ZodString;
|
|
6
6
|
remember_me: z.ZodDefault<z.ZodBoolean>;
|
|
7
7
|
}, z.core.$strip>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/sign-in/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/sign-in/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,KAAK,yBAAyB,CAAA;AAE3C,eAAO,MAAM,aAAa;;;;iBAOxB,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAE1D,eAAO,MAAM,cAAc;;;;;iBAKzB,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/sign-up/handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/sign-up/handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAA8B,MAAM,cAAc,CAAA;AAG9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBAgFlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAEC"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { z } from '../../../../vite/node_modules/zod';
|
|
2
2
|
export declare const Route = "/api/rb/auth/sign-up";
|
|
3
3
|
export declare const requestSchema: z.ZodObject<{
|
|
4
|
-
|
|
4
|
+
email: z.ZodString;
|
|
5
5
|
password: z.ZodString;
|
|
6
|
-
password_confirmation: z.ZodString;
|
|
7
6
|
remember_me: z.ZodDefault<z.ZodBoolean>;
|
|
8
7
|
}, z.core.$strip>;
|
|
9
8
|
export type RequestPayload = z.infer<typeof requestSchema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/sign-up/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/sign-up/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,KAAK,yBAAyB,CAAA;AAE3C,eAAO,MAAM,aAAa;;;;iBAQtB,CAAA;AAEJ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAE1D,eAAO,MAAM,cAAc;;;;;iBAKzB,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/api/verify-otp/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAA8B,MAAM,cAAc,CAAA;AAE9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;yBA0DlC,KAAK,GAAG,CAAC,eAAe,CAAC;AAAzC,wBAEC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from '../../../../vite/node_modules/zod';
|
|
2
|
+
export declare const Route = "/api/rb/auth/verify-otp";
|
|
3
|
+
export declare const requestSchema: z.ZodObject<{
|
|
4
|
+
email: z.ZodString;
|
|
5
|
+
code: z.ZodString;
|
|
6
|
+
remember_me: z.ZodDefault<z.ZodBoolean>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
export type RequestPayload = z.infer<typeof requestSchema>;
|
|
9
|
+
export declare const responseSchema: z.ZodObject<{
|
|
10
|
+
success: z.ZodBoolean;
|
|
11
|
+
error: z.ZodOptional<z.ZodString>;
|
|
12
|
+
user_id: z.ZodOptional<z.ZodString>;
|
|
13
|
+
tenant_id: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
export type ResponsePayload = z.infer<typeof responseSchema>;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/verify-otp/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,KAAK,4BAA4B,CAAA;AAE9C,eAAO,MAAM,aAAa;;;;iBAIxB,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAE1D,eAAO,MAAM,cAAc;;;;;iBAKzB,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/EmailInput/index.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,GAAI,iCAIxB;IACD,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,4CA2BA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PasswordInput/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PasswordInput/index.tsx"],"names":[],"mappings":"AAKA,KAAK,kBAAkB,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,qDAM3B,kBAAkB,4CA2CpB,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
export declare const SignUpForm: ({ children, className }: {
|
|
2
|
+
export declare const SignUpForm: ({ children, className, otpNextPath }: {
|
|
3
3
|
children: ReactNode;
|
|
4
4
|
className?: string;
|
|
5
|
+
otpNextPath?: string;
|
|
5
6
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SignUpForm/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAsB,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SignUpForm/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAsB,MAAM,OAAO,CAAA;AAYpD,eAAO,MAAM,UAAU,GAAI,sCAIxB;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,4CA8EA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import { loadModel } from "@rpcbase/api";
|
|
3
|
+
import { hashPassword, sendEmail } from "@rpcbase/server";
|
|
4
|
+
import { R as Route, r as requestSchema } from "./index-DwX0Y2YV.js";
|
|
5
|
+
const signUp = async (payload, ctx) => {
|
|
6
|
+
const User = await loadModel("User", ctx);
|
|
7
|
+
const Tenant = await loadModel("Tenant", ctx);
|
|
8
|
+
const parsed = requestSchema.safeParse(payload);
|
|
9
|
+
if (!parsed.success) {
|
|
10
|
+
ctx.res.status(400);
|
|
11
|
+
return { success: false, error: "invalid_payload" };
|
|
12
|
+
}
|
|
13
|
+
const { email, password, remember_me: _remember_me } = parsed.data;
|
|
14
|
+
const existingUser = await User.findOne({ email });
|
|
15
|
+
if (existingUser) {
|
|
16
|
+
console.log("user with email already exists", email);
|
|
17
|
+
ctx.res.status(409);
|
|
18
|
+
return { success: false, error: "user_exists" };
|
|
19
|
+
}
|
|
20
|
+
const salt = crypto.randomBytes(16).toString("hex");
|
|
21
|
+
const derivedKey = await hashPassword(password, salt);
|
|
22
|
+
const hashedPassword = `${salt}:${derivedKey.toString("hex")}`;
|
|
23
|
+
const tenantId = crypto.randomUUID();
|
|
24
|
+
const emailVerificationCode = crypto.randomInt(0, 1e6).toString().padStart(6, "0");
|
|
25
|
+
const emailVerificationExpiresAt = new Date(Date.now() + 10 * 60 * 1e3);
|
|
26
|
+
const user = new User({
|
|
27
|
+
email,
|
|
28
|
+
password: hashedPassword,
|
|
29
|
+
tenants: [tenantId],
|
|
30
|
+
email_verification_code: emailVerificationCode,
|
|
31
|
+
email_verification_expires_at: emailVerificationExpiresAt
|
|
32
|
+
});
|
|
33
|
+
await user.save();
|
|
34
|
+
try {
|
|
35
|
+
await sendEmail({
|
|
36
|
+
to: email,
|
|
37
|
+
subject: `Verify your email: ${emailVerificationCode}`,
|
|
38
|
+
html: `
|
|
39
|
+
<p>Welcome to rpcbase!</p>
|
|
40
|
+
<p>Your verification code is <strong>${emailVerificationCode}</strong>. It expires in 10 minutes.</p>
|
|
41
|
+
<p>If you didn't request this, you can ignore this message.</p>
|
|
42
|
+
`,
|
|
43
|
+
text: `Welcome to rpcbase! Your verification code is ${emailVerificationCode}. It expires in 10 minutes. If you didn't request this, you can ignore this message.`
|
|
44
|
+
});
|
|
45
|
+
} catch (err) {
|
|
46
|
+
console.warn("failed to send sign-up email", err);
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
await Tenant.create({
|
|
50
|
+
tenant_id: tenantId,
|
|
51
|
+
name: email
|
|
52
|
+
});
|
|
53
|
+
} catch (err) {
|
|
54
|
+
console.warn("failed to create tenant for user", err);
|
|
55
|
+
}
|
|
56
|
+
console.log("created new user", user._id.toString());
|
|
57
|
+
return { success: true, user_id: user._id.toString(), tenant_id: tenantId };
|
|
58
|
+
};
|
|
59
|
+
const handler = (api) => {
|
|
60
|
+
api.post(Route, signUp);
|
|
61
|
+
};
|
|
62
|
+
export {
|
|
63
|
+
handler as default
|
|
64
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { loadModel } from "@rpcbase/api";
|
|
2
|
+
import { o as object, b as boolean, s as string } from "./schemas-KL7REOdt.js";
|
|
3
|
+
const Route = "/api/rb/auth/verify-otp";
|
|
4
|
+
const requestSchema = object({
|
|
5
|
+
email: string().email(),
|
|
6
|
+
code: string().length(6, "Code must be 6 digits"),
|
|
7
|
+
remember_me: boolean().default(true)
|
|
8
|
+
});
|
|
9
|
+
object({
|
|
10
|
+
success: boolean(),
|
|
11
|
+
error: string().optional(),
|
|
12
|
+
user_id: string().optional(),
|
|
13
|
+
tenant_id: string().optional()
|
|
14
|
+
});
|
|
15
|
+
const verifyOtp = async (payload, ctx) => {
|
|
16
|
+
const User = await loadModel("User", ctx);
|
|
17
|
+
const parsed = requestSchema.safeParse(payload);
|
|
18
|
+
if (!parsed.success) {
|
|
19
|
+
ctx.res.status(400);
|
|
20
|
+
return { success: false, error: "invalid_payload" };
|
|
21
|
+
}
|
|
22
|
+
const { email, code } = parsed.data;
|
|
23
|
+
const user = await User.findOne({ email }, { email_verification_code: 1, email_verification_expires_at: 1, tenants: 1 });
|
|
24
|
+
if (!user) {
|
|
25
|
+
ctx.res.status(404);
|
|
26
|
+
return { success: false, error: "user_not_found" };
|
|
27
|
+
}
|
|
28
|
+
const storedCode = user.email_verification_code;
|
|
29
|
+
const expiresAt = user.email_verification_expires_at;
|
|
30
|
+
const isExpired = expiresAt instanceof Date && expiresAt.getTime() < Date.now();
|
|
31
|
+
if (!storedCode || storedCode !== code || isExpired) {
|
|
32
|
+
ctx.res.status(400);
|
|
33
|
+
return { success: false, error: "invalid_code" };
|
|
34
|
+
}
|
|
35
|
+
user.email_verification_code = void 0;
|
|
36
|
+
user.email_verification_expires_at = void 0;
|
|
37
|
+
await user.save();
|
|
38
|
+
const tenantId = user.tenants?.[0]?.toString?.() || "00000000";
|
|
39
|
+
const signedInTenants = (user.tenants || []).map((t) => t.toString?.() || String(t)) || [tenantId];
|
|
40
|
+
if (!ctx.req.session) {
|
|
41
|
+
ctx.res.status(500);
|
|
42
|
+
return { success: false, error: "session_unavailable" };
|
|
43
|
+
}
|
|
44
|
+
ctx.req.session.user = {
|
|
45
|
+
id: user._id.toString(),
|
|
46
|
+
current_tenant_id: tenantId,
|
|
47
|
+
signed_in_tenants: signedInTenants.length ? signedInTenants : [tenantId],
|
|
48
|
+
is_entry_gate_authorized: true
|
|
49
|
+
};
|
|
50
|
+
return { success: true, user_id: user._id.toString(), tenant_id: tenantId };
|
|
51
|
+
};
|
|
52
|
+
const handler = (api) => {
|
|
53
|
+
api.post(Route, verifyOtp);
|
|
54
|
+
};
|
|
55
|
+
export {
|
|
56
|
+
handler as default
|
|
57
|
+
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import crypto from "crypto";
|
|
2
|
-
import { i as isEmail } from "./isEmail-IG0hXiQk.js";
|
|
3
2
|
import { loadModel } from "@rpcbase/api";
|
|
4
3
|
import { hashPassword } from "@rpcbase/server";
|
|
5
|
-
import { R as Route, r as requestSchema } from "./index-
|
|
4
|
+
import { R as Route, r as requestSchema } from "./index-Bdcryyvv.js";
|
|
6
5
|
const signIn = async (payload, ctx) => {
|
|
7
6
|
const User = await loadModel("User", ctx);
|
|
8
7
|
const parsed = requestSchema.safeParse(payload);
|
|
@@ -10,9 +9,8 @@ const signIn = async (payload, ctx) => {
|
|
|
10
9
|
ctx.res.status(400);
|
|
11
10
|
return { success: false, error: "invalid_payload" };
|
|
12
11
|
}
|
|
13
|
-
const {
|
|
14
|
-
const
|
|
15
|
-
const user = await User.findOne(query, { password: 1, tenants: 1 });
|
|
12
|
+
const { email, password } = parsed.data;
|
|
13
|
+
const user = await User.findOne({ email }, { password: 1, tenants: 1 });
|
|
16
14
|
if (!user?.password) {
|
|
17
15
|
ctx.res.status(401);
|
|
18
16
|
return { success: false, error: "invalid_credentials" };
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import { i as isValidNumber } from "./isValidNumber-6pMDGLRn.js";
|
|
2
1
|
import { o as object, b as boolean, s as string } from "./schemas-KL7REOdt.js";
|
|
3
2
|
const Route = "/api/rb/auth/sign-in";
|
|
4
3
|
const requestSchema = object({
|
|
5
|
-
|
|
6
|
-
(value) => {
|
|
7
|
-
const isEmail = string().email().safeParse(value).success;
|
|
8
|
-
const isPhone = isValidNumber(value);
|
|
9
|
-
return isEmail || isPhone;
|
|
10
|
-
},
|
|
11
|
-
"Please enter a valid email address or phone number"
|
|
12
|
-
),
|
|
4
|
+
email: string().nonempty("Email is required").email("Please enter a valid email address"),
|
|
13
5
|
password: string().min(1, { message: "Password is required" }),
|
|
14
6
|
remember_me: boolean().default(true)
|
|
15
7
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { o as object, b as boolean, s as string } from "./schemas-KL7REOdt.js";
|
|
2
|
+
const Route = "/api/rb/auth/sign-up";
|
|
3
|
+
const requestSchema = object({
|
|
4
|
+
email: string().nonempty("Email is required").email("Please enter a valid email address"),
|
|
5
|
+
password: string().min(8, { message: "Password must be at least 8 characters long." }),
|
|
6
|
+
remember_me: boolean().default(true)
|
|
7
|
+
});
|
|
8
|
+
object({
|
|
9
|
+
success: boolean(),
|
|
10
|
+
error: string().optional(),
|
|
11
|
+
user_id: string().optional(),
|
|
12
|
+
tenant_id: string().optional()
|
|
13
|
+
});
|
|
14
|
+
export {
|
|
15
|
+
Route as R,
|
|
16
|
+
requestSchema as r
|
|
17
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useLocation, Link } from "@rpcbase/router";
|
|
2
|
+
import { useLocation, Link, useNavigate } from "@rpcbase/router";
|
|
3
3
|
import clsx from "clsx";
|
|
4
4
|
import { useFormContext, useForm, zodResolver, FormProvider } from "@rpcbase/form";
|
|
5
|
+
import * as React from "react";
|
|
5
6
|
import { useEffect, useState } from "react";
|
|
6
|
-
import { r as requestSchema } from "./index-
|
|
7
|
-
import { r as requestSchema$1 } from "./index-
|
|
7
|
+
import { r as requestSchema } from "./index-Bdcryyvv.js";
|
|
8
|
+
import { r as requestSchema$1 } from "./index-DwX0Y2YV.js";
|
|
8
9
|
import { b, a, r } from "./middleware-BiMXO6Dq.js";
|
|
9
10
|
const LINKS_REDIRECTION_MAP = {
|
|
10
11
|
"/auth/sign-in": {
|
|
@@ -78,13 +79,13 @@ const AppleSignInButton = ({
|
|
|
78
79
|
}
|
|
79
80
|
);
|
|
80
81
|
};
|
|
81
|
-
const
|
|
82
|
+
const EmailInput = ({
|
|
82
83
|
id,
|
|
83
84
|
className,
|
|
84
85
|
placeholder
|
|
85
86
|
}) => {
|
|
86
87
|
const { register, formState } = useFormContext();
|
|
87
|
-
const error = formState.errors.
|
|
88
|
+
const error = formState.errors.email;
|
|
88
89
|
let errorMessage;
|
|
89
90
|
if (typeof error === "string") {
|
|
90
91
|
errorMessage = error;
|
|
@@ -96,12 +97,12 @@ const EmailOrPhoneInput = ({
|
|
|
96
97
|
"input",
|
|
97
98
|
{
|
|
98
99
|
id,
|
|
99
|
-
type: "
|
|
100
|
+
type: "email",
|
|
100
101
|
required: true,
|
|
101
|
-
autoComplete: "
|
|
102
|
+
autoComplete: "email",
|
|
102
103
|
className,
|
|
103
104
|
placeholder,
|
|
104
|
-
...register("
|
|
105
|
+
...register("email")
|
|
105
106
|
}
|
|
106
107
|
),
|
|
107
108
|
errorMessage ? /* @__PURE__ */ jsx("p", { className: "mt-1 -mb-2 text-sm/6 text-red-500", children: errorMessage }) : null
|
|
@@ -113,7 +114,7 @@ const SignInForm = ({
|
|
|
113
114
|
}) => {
|
|
114
115
|
const methods = useForm({
|
|
115
116
|
defaultValues: {
|
|
116
|
-
|
|
117
|
+
email: "",
|
|
117
118
|
password: "",
|
|
118
119
|
remember_me: true
|
|
119
120
|
},
|
|
@@ -145,14 +146,15 @@ const SignInForm = ({
|
|
|
145
146
|
};
|
|
146
147
|
const SignUpForm = ({
|
|
147
148
|
children,
|
|
148
|
-
className
|
|
149
|
+
className,
|
|
150
|
+
otpNextPath
|
|
149
151
|
}) => {
|
|
152
|
+
const navigate = useNavigate();
|
|
150
153
|
const [serverMessage, setServerMessage] = useState(null);
|
|
151
154
|
const methods = useForm({
|
|
152
155
|
defaultValues: {
|
|
153
|
-
|
|
156
|
+
email: "",
|
|
154
157
|
password: "",
|
|
155
|
-
password_confirmation: "",
|
|
156
158
|
remember_me: true
|
|
157
159
|
},
|
|
158
160
|
resolver: zodResolver(requestSchema$1)
|
|
@@ -173,7 +175,7 @@ const SignUpForm = ({
|
|
|
173
175
|
console.log("SIGN UP RESPONSE", json);
|
|
174
176
|
if (!res.ok) {
|
|
175
177
|
console.error("Sign-up failed", json);
|
|
176
|
-
const message = json.error === "user_exists" ? "An account already exists with this email
|
|
178
|
+
const message = json.error === "user_exists" ? "An account already exists with this email." : "Sign-up failed. Please try again.";
|
|
177
179
|
methods.setError("root", { type: "server", message });
|
|
178
180
|
return;
|
|
179
181
|
}
|
|
@@ -181,8 +183,12 @@ const SignUpForm = ({
|
|
|
181
183
|
methods.setError("root", { type: "server", message: "Sign-up failed. Please try again." });
|
|
182
184
|
return;
|
|
183
185
|
}
|
|
186
|
+
const search = new URLSearchParams({ email: data.email });
|
|
187
|
+
if (otpNextPath) {
|
|
188
|
+
search.set("next", otpNextPath);
|
|
189
|
+
}
|
|
190
|
+
navigate(`/auth/sign-up-otp?${search.toString()}`);
|
|
184
191
|
setServerMessage("Account created. Check your inbox to verify your email.");
|
|
185
|
-
methods.reset();
|
|
186
192
|
} catch (err) {
|
|
187
193
|
console.error("Sign-up request error", err);
|
|
188
194
|
methods.setError("root", { type: "server", message: "Network error. Please try again." });
|
|
@@ -220,6 +226,58 @@ const RememberMeCheckbox = ({
|
|
|
220
226
|
)
|
|
221
227
|
] });
|
|
222
228
|
};
|
|
229
|
+
function EyeSlashIcon({
|
|
230
|
+
title,
|
|
231
|
+
titleId,
|
|
232
|
+
...props
|
|
233
|
+
}, svgRef) {
|
|
234
|
+
return /* @__PURE__ */ React.createElement("svg", Object.assign({
|
|
235
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
236
|
+
fill: "none",
|
|
237
|
+
viewBox: "0 0 24 24",
|
|
238
|
+
strokeWidth: 1.5,
|
|
239
|
+
stroke: "currentColor",
|
|
240
|
+
"aria-hidden": "true",
|
|
241
|
+
"data-slot": "icon",
|
|
242
|
+
ref: svgRef,
|
|
243
|
+
"aria-labelledby": titleId
|
|
244
|
+
}, props), title ? /* @__PURE__ */ React.createElement("title", {
|
|
245
|
+
id: titleId
|
|
246
|
+
}, title) : null, /* @__PURE__ */ React.createElement("path", {
|
|
247
|
+
strokeLinecap: "round",
|
|
248
|
+
strokeLinejoin: "round",
|
|
249
|
+
d: "M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88"
|
|
250
|
+
}));
|
|
251
|
+
}
|
|
252
|
+
const ForwardRef$1 = /* @__PURE__ */ React.forwardRef(EyeSlashIcon);
|
|
253
|
+
function EyeIcon({
|
|
254
|
+
title,
|
|
255
|
+
titleId,
|
|
256
|
+
...props
|
|
257
|
+
}, svgRef) {
|
|
258
|
+
return /* @__PURE__ */ React.createElement("svg", Object.assign({
|
|
259
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
260
|
+
fill: "none",
|
|
261
|
+
viewBox: "0 0 24 24",
|
|
262
|
+
strokeWidth: 1.5,
|
|
263
|
+
stroke: "currentColor",
|
|
264
|
+
"aria-hidden": "true",
|
|
265
|
+
"data-slot": "icon",
|
|
266
|
+
ref: svgRef,
|
|
267
|
+
"aria-labelledby": titleId
|
|
268
|
+
}, props), title ? /* @__PURE__ */ React.createElement("title", {
|
|
269
|
+
id: titleId
|
|
270
|
+
}, title) : null, /* @__PURE__ */ React.createElement("path", {
|
|
271
|
+
strokeLinecap: "round",
|
|
272
|
+
strokeLinejoin: "round",
|
|
273
|
+
d: "M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
|
|
274
|
+
}), /* @__PURE__ */ React.createElement("path", {
|
|
275
|
+
strokeLinecap: "round",
|
|
276
|
+
strokeLinejoin: "round",
|
|
277
|
+
d: "M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
const ForwardRef = /* @__PURE__ */ React.forwardRef(EyeIcon);
|
|
223
281
|
const PasswordInput = ({
|
|
224
282
|
id,
|
|
225
283
|
name = "password",
|
|
@@ -227,28 +285,42 @@ const PasswordInput = ({
|
|
|
227
285
|
placeholder,
|
|
228
286
|
autoComplete = "current-password"
|
|
229
287
|
}) => {
|
|
288
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
230
289
|
const { register, formState } = useFormContext();
|
|
231
290
|
const fieldError = formState.errors[name];
|
|
232
291
|
const errorMessage = typeof fieldError === "string" ? fieldError : typeof fieldError?.message === "string" ? fieldError.message : void 0;
|
|
292
|
+
const inputClassName = className ? `${className} pr-11` : "pr-11";
|
|
233
293
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
234
|
-
/* @__PURE__ */
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
294
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
295
|
+
/* @__PURE__ */ jsx(
|
|
296
|
+
"input",
|
|
297
|
+
{
|
|
298
|
+
id,
|
|
299
|
+
type: showPassword ? "text" : "password",
|
|
300
|
+
autoComplete,
|
|
301
|
+
className: inputClassName,
|
|
302
|
+
placeholder,
|
|
303
|
+
...register(name)
|
|
304
|
+
}
|
|
305
|
+
),
|
|
306
|
+
/* @__PURE__ */ jsx(
|
|
307
|
+
"button",
|
|
308
|
+
{
|
|
309
|
+
type: "button",
|
|
310
|
+
className: "absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500",
|
|
311
|
+
onClick: () => setShowPassword((prev) => !prev),
|
|
312
|
+
"aria-label": showPassword ? "Hide characters" : "Show characters",
|
|
313
|
+
children: showPassword ? /* @__PURE__ */ jsx(ForwardRef$1, { className: "h-5 w-5", "aria-hidden": true }) : /* @__PURE__ */ jsx(ForwardRef, { className: "h-5 w-5", "aria-hidden": true })
|
|
314
|
+
}
|
|
315
|
+
)
|
|
316
|
+
] }),
|
|
245
317
|
errorMessage ? /* @__PURE__ */ jsx("p", { className: "mt-1 -mb-2 text-sm/6 text-red-500", children: errorMessage }) : null
|
|
246
318
|
] });
|
|
247
319
|
};
|
|
248
320
|
export {
|
|
249
321
|
AppleSignInButton,
|
|
250
322
|
AuthLayout,
|
|
251
|
-
|
|
323
|
+
EmailInput,
|
|
252
324
|
PasswordInput,
|
|
253
325
|
RememberMeCheckbox,
|
|
254
326
|
SignInForm,
|
package/dist/routes.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const routes = Object.entries({
|
|
2
|
-
.../* @__PURE__ */ Object.assign({ "./api/me/handler.ts": () => import("./handler-Ba3pgtfZ.js"), "./api/sign-in/handler.ts": () => import("./handler-
|
|
2
|
+
.../* @__PURE__ */ Object.assign({ "./api/me/handler.ts": () => import("./handler-Ba3pgtfZ.js"), "./api/sign-in/handler.ts": () => import("./handler-r4ZECW_z.js"), "./api/sign-out/handler.ts": () => import("./handler-CNHucHrj.js"), "./api/sign-up/handler.ts": () => import("./handler-CE4lXc0G.js"), "./api/verify-otp/handler.ts": () => import("./handler-DOnLMd-9.js") })
|
|
3
3
|
}).reduce((acc, [path, mod]) => {
|
|
4
4
|
acc[path.replace("./api/", "@rpcbase/auth/api/")] = mod;
|
|
5
5
|
return acc;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rpcbase/auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.47.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -38,6 +38,13 @@
|
|
|
38
38
|
"dist/"
|
|
39
39
|
]
|
|
40
40
|
},
|
|
41
|
+
"build-watch": {
|
|
42
|
+
"command": "../../node_modules/.bin/vite build --watch",
|
|
43
|
+
"service": true,
|
|
44
|
+
"dependencies": [
|
|
45
|
+
"build"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
41
48
|
"release": {
|
|
42
49
|
"command": "../../scripts/publish.js",
|
|
43
50
|
"dependencies": [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/EmailOrPhoneInput/index.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,GAAI,iCAI/B;IACD,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,4CA6BA,CAAA"}
|
package/dist/handler-rZR_dx7n.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import crypto from "crypto";
|
|
2
|
-
import { i as isEmail } from "./isEmail-IG0hXiQk.js";
|
|
3
|
-
import { loadModel } from "@rpcbase/api";
|
|
4
|
-
import { hashPassword, sendEmail } from "@rpcbase/server";
|
|
5
|
-
import { R as Route, r as requestSchema } from "./index-Cq04nmsE.js";
|
|
6
|
-
const signUp = async (payload, ctx) => {
|
|
7
|
-
const User = await loadModel("User", ctx);
|
|
8
|
-
const Tenant = await loadModel("Tenant", ctx);
|
|
9
|
-
const parsed = requestSchema.safeParse(payload);
|
|
10
|
-
if (!parsed.success) {
|
|
11
|
-
ctx.res.status(400);
|
|
12
|
-
return { success: false, error: "invalid_payload" };
|
|
13
|
-
}
|
|
14
|
-
const { email_or_phone, password, remember_me: _remember_me } = parsed.data;
|
|
15
|
-
const is_email = isEmail(email_or_phone);
|
|
16
|
-
const query = is_email ? { email: email_or_phone } : { phone: email_or_phone };
|
|
17
|
-
const existingUser = await User.findOne(query);
|
|
18
|
-
if (existingUser) {
|
|
19
|
-
console.log("user with email or phone already exists", email_or_phone);
|
|
20
|
-
ctx.res.status(409);
|
|
21
|
-
return { success: false, error: "user_exists" };
|
|
22
|
-
}
|
|
23
|
-
const salt = crypto.randomBytes(16).toString("hex");
|
|
24
|
-
const derivedKey = await hashPassword(password, salt);
|
|
25
|
-
const hashedPassword = `${salt}:${derivedKey.toString("hex")}`;
|
|
26
|
-
const tenantId = crypto.randomUUID();
|
|
27
|
-
const user = new User({
|
|
28
|
-
...query,
|
|
29
|
-
password: hashedPassword,
|
|
30
|
-
tenants: [tenantId]
|
|
31
|
-
});
|
|
32
|
-
await user.save();
|
|
33
|
-
if (is_email) {
|
|
34
|
-
try {
|
|
35
|
-
await sendEmail({
|
|
36
|
-
to: email_or_phone,
|
|
37
|
-
subject: "Verify your email",
|
|
38
|
-
html: "<p>Welcome to rpcbase!</p><p>We created your account. Use this email to sign in and finish verification.</p>",
|
|
39
|
-
text: "Welcome to rpcbase! We created your account. Use this email to sign in and finish verification."
|
|
40
|
-
});
|
|
41
|
-
} catch (err) {
|
|
42
|
-
console.warn("failed to send sign-up email", err);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
try {
|
|
46
|
-
await Tenant.create({
|
|
47
|
-
tenant_id: tenantId,
|
|
48
|
-
name: query.email || query.phone
|
|
49
|
-
});
|
|
50
|
-
} catch (err) {
|
|
51
|
-
console.warn("failed to create tenant for user", err);
|
|
52
|
-
}
|
|
53
|
-
console.log("created new user", user._id.toString());
|
|
54
|
-
if (!ctx.req.session) {
|
|
55
|
-
ctx.res.status(500);
|
|
56
|
-
return { success: false, error: "session_unavailable" };
|
|
57
|
-
}
|
|
58
|
-
ctx.req.session.user = {
|
|
59
|
-
id: user._id.toString(),
|
|
60
|
-
current_tenant_id: tenantId,
|
|
61
|
-
signed_in_tenants: [tenantId],
|
|
62
|
-
is_entry_gate_authorized: true
|
|
63
|
-
};
|
|
64
|
-
return { success: true, user_id: user._id.toString(), tenant_id: tenantId };
|
|
65
|
-
};
|
|
66
|
-
const handler = (api) => {
|
|
67
|
-
api.post(Route, signUp);
|
|
68
|
-
};
|
|
69
|
-
export {
|
|
70
|
-
handler as default
|
|
71
|
-
};
|
package/dist/index-Cq04nmsE.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { i as isValidNumber } from "./isValidNumber-6pMDGLRn.js";
|
|
2
|
-
import { o as object, b as boolean, s as string } from "./schemas-KL7REOdt.js";
|
|
3
|
-
const Route = "/api/rb/auth/sign-up";
|
|
4
|
-
const requestSchema = object({
|
|
5
|
-
email_or_phone: string().nonempty("Email or phone number is required").refine(
|
|
6
|
-
(value) => {
|
|
7
|
-
const isEmail = string().email().safeParse(value).success;
|
|
8
|
-
const isPhone = isValidNumber(value);
|
|
9
|
-
return isEmail || isPhone;
|
|
10
|
-
},
|
|
11
|
-
"Please enter a valid email address or phone number"
|
|
12
|
-
),
|
|
13
|
-
password: string().min(8, { message: "Password must be at least 8 characters long." }),
|
|
14
|
-
password_confirmation: string().nonempty({ message: "Please confirm your password." }),
|
|
15
|
-
remember_me: boolean().default(true)
|
|
16
|
-
}).refine((data) => data.password === data.password_confirmation, {
|
|
17
|
-
message: "Passwords do not match.",
|
|
18
|
-
path: ["password_confirmation"]
|
|
19
|
-
});
|
|
20
|
-
object({
|
|
21
|
-
success: boolean(),
|
|
22
|
-
error: string().optional(),
|
|
23
|
-
user_id: string().optional(),
|
|
24
|
-
tenant_id: string().optional()
|
|
25
|
-
});
|
|
26
|
-
export {
|
|
27
|
-
Route as R,
|
|
28
|
-
requestSchema as r
|
|
29
|
-
};
|