@intelligo-dev/auth 1.0.0-beta.1 → 1.0.0-beta.13
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/NOTICE +6 -0
- package/README.md +59 -0
- package/dist/client.js +6 -16
- package/dist/client.js.map +1 -1
- package/dist/edge.js +22 -28
- package/dist/edge.js.map +1 -1
- package/dist/guard-error.js +23 -0
- package/dist/guard-error.js.map +1 -0
- package/dist/helpers.js +77 -97
- package/dist/helpers.js.map +1 -1
- package/dist/impersonation.js +46 -18
- package/dist/impersonation.js.map +1 -1
- package/dist/index.js +21 -27
- package/dist/index.js.map +1 -1
- package/dist/invitation-links.js +13 -0
- package/dist/invitation-links.js.map +1 -0
- package/dist/onboarding/errors.js +4 -14
- package/dist/onboarding/errors.js.map +1 -1
- package/dist/onboarding/schemas.js +3 -15
- package/dist/onboarding/schemas.js.map +1 -1
- package/dist/onboarding/service.js +14 -68
- package/dist/onboarding/service.js.map +1 -1
- package/dist/org-api.js +10 -67
- package/dist/org-api.js.map +1 -1
- package/dist/profile/errors.js +4 -14
- package/dist/profile/errors.js.map +1 -1
- package/dist/profile/schemas.js +1 -10
- package/dist/profile/schemas.js.map +1 -1
- package/dist/profile/service.js +12 -53
- package/dist/profile/service.js.map +1 -1
- package/dist/roles.js +28 -5
- package/dist/roles.js.map +1 -1
- package/dist/server.js +80 -98
- package/dist/server.js.map +1 -1
- package/dist/team/errors.js +4 -13
- package/dist/team/errors.js.map +1 -1
- package/dist/team/schemas.js +4 -18
- package/dist/team/schemas.js.map +1 -1
- package/dist/team/service.js +80 -157
- package/dist/team/service.js.map +1 -1
- package/dist/trusted-origins.js +25 -0
- package/dist/trusted-origins.js.map +1 -0
- package/dist/workspace/errors.js +4 -14
- package/dist/workspace/errors.js.map +1 -1
- package/dist/workspace/schemas.js +2 -18
- package/dist/workspace/schemas.js.map +1 -1
- package/dist/workspace/service.js +31 -91
- package/dist/workspace/service.js.map +1 -1
- package/dist/workspace-bootstrap.js +33 -0
- package/dist/workspace-bootstrap.js.map +1 -0
- package/dist/workspace-init.js +46 -51
- package/dist/workspace-init.js.map +1 -1
- package/dist/workspace-slug.js +29 -0
- package/dist/workspace-slug.js.map +1 -0
- package/package.json +36 -14
- package/src/client.ts +6 -16
- package/src/edge.ts +22 -28
- package/src/guard-error.ts +36 -0
- package/src/helpers.ts +99 -114
- package/src/impersonation.ts +52 -17
- package/src/index.ts +14 -10
- package/src/invitation-links.ts +15 -0
- package/src/onboarding/errors.ts +5 -17
- package/src/onboarding/schemas.ts +3 -15
- package/src/onboarding/service.ts +11 -65
- package/src/org-api.ts +9 -66
- package/src/profile/errors.ts +5 -17
- package/src/profile/schemas.ts +1 -10
- package/src/profile/service.ts +8 -49
- package/src/roles.ts +36 -5
- package/src/server.ts +86 -104
- package/src/team/errors.ts +4 -13
- package/src/team/schemas.ts +4 -18
- package/src/team/service.ts +100 -174
- package/src/trusted-origins.ts +26 -0
- package/src/workspace/errors.ts +4 -14
- package/src/workspace/schemas.ts +2 -18
- package/src/workspace/service.ts +40 -92
- package/src/workspace-bootstrap.ts +57 -0
- package/src/workspace-init.ts +55 -56
- package/src/workspace-slug.ts +32 -0
package/dist/server.js
CHANGED
|
@@ -1,59 +1,65 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Better-Auth
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* - Email + password authentication
|
|
6
|
-
* - OAuth providers (Google, GitHub) with graceful env var fallback
|
|
7
|
-
* - Drizzle database adapter
|
|
8
|
-
* - Session persistence (7-day expiration, 1-day update age)
|
|
9
|
-
* - Organization plugin for multi-tenant workspace support (Phase 10)
|
|
10
|
-
* - Email sending via Resend for verification, password reset, welcome (Phase 14)
|
|
2
|
+
* The Better-Auth instance: email + password, optional Google/GitHub OAuth,
|
|
3
|
+
* organizations as workspaces, and the admin plugin for impersonation.
|
|
4
|
+
* Configured at module load; reaches the database and email provider.
|
|
11
5
|
*/
|
|
12
6
|
import { betterAuth } from "better-auth";
|
|
13
7
|
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
|
14
8
|
import { admin, organization } from "better-auth/plugins";
|
|
15
9
|
import { createAccessControl } from "better-auth/plugins/access";
|
|
16
10
|
import { adminAc, defaultStatements, userAc, } from "better-auth/plugins/admin/access";
|
|
17
|
-
import { PLATFORM_ADMIN_ROLE } from "./roles";
|
|
11
|
+
import { PLATFORM_ADMIN_ROLE } from "./roles.js";
|
|
12
|
+
import { resolveTrustedOrigins } from "./trusted-origins.js";
|
|
18
13
|
/**
|
|
19
|
-
* Access control for the platform role.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* backs — "Invalid admin roles" at build time — which is the right
|
|
23
|
-
* behaviour: it stops a typo from silently granting nothing, or a
|
|
24
|
-
* renamed role from silently granting everything. `platform-admin`
|
|
25
|
-
* takes the plugin's own admin statements unchanged; the product
|
|
26
|
-
* defines no extra platform permissions yet.
|
|
14
|
+
* Access control for the platform role. Better-Auth refuses an `adminRoles`
|
|
15
|
+
* entry no role definition backs ("Invalid admin roles"); `platform-admin`
|
|
16
|
+
* takes the plugin's own admin statements unchanged.
|
|
27
17
|
*/
|
|
28
18
|
const accessControl = createAccessControl(defaultStatements);
|
|
29
19
|
const platformAdminRole = accessControl.newRole(adminAc.statements);
|
|
30
20
|
const userRole = accessControl.newRole(userAc.statements);
|
|
31
21
|
import { db } from "@intelligo-dev/core/db";
|
|
32
22
|
import { users, sessions, accounts, verifications, organization as organizationTable, member, invitation, } from "@intelligo-dev/core/db/schema";
|
|
33
|
-
import { sendVerifyEmail, sendPasswordResetEmail, sendWelcomeEmail, sendInvitationEmail, } from "@intelligo-dev/core/email";
|
|
23
|
+
import { ConsoleProvider, getEmailProvider, sendVerifyEmail, sendPasswordResetEmail, sendWelcomeEmail, sendInvitationEmail, } from "@intelligo-dev/core/email";
|
|
34
24
|
import { eq } from "drizzle-orm";
|
|
25
|
+
import { invitationLinks } from "./invitation-links.js";
|
|
26
|
+
import { personalWorkspaceSlug } from "./workspace-slug.js";
|
|
27
|
+
import { workspaceCreated } from "./workspace-bootstrap.js";
|
|
28
|
+
/**
|
|
29
|
+
* The origin this app is served from. `NEXT_PUBLIC_APP_URL` is required, but
|
|
30
|
+
* auth is configured at module load, before any composition root asserts it,
|
|
31
|
+
* and the absolute links in email still need a concrete host.
|
|
32
|
+
*/
|
|
33
|
+
const APP_URL = process.env.NEXT_PUBLIC_APP_URL ?? "http://localhost:4000";
|
|
34
|
+
/**
|
|
35
|
+
* Origins the CSRF check accepts. The fallback above must NOT apply here:
|
|
36
|
+
* a guessed port rejects every sign-in. See `resolveTrustedOrigins`.
|
|
37
|
+
*/
|
|
38
|
+
const TRUSTED_ORIGINS = resolveTrustedOrigins(process.env);
|
|
35
39
|
export const auth = betterAuth({
|
|
40
|
+
// Explicit, so the documented name is the one honoured; AUTH_SECRET is
|
|
41
|
+
// accepted as an alias.
|
|
42
|
+
secret: process.env.BETTER_AUTH_SECRET ?? process.env.AUTH_SECRET,
|
|
36
43
|
database: drizzleAdapter(db, {
|
|
37
44
|
provider: "pg",
|
|
38
|
-
// Map our schema tables to Better-Auth's expected names
|
|
39
45
|
schema: {
|
|
40
46
|
user: users,
|
|
41
47
|
session: sessions,
|
|
42
48
|
account: accounts,
|
|
43
49
|
verification: verifications,
|
|
44
|
-
// Organization plugin tables (Phase 10)
|
|
45
50
|
organization: organizationTable,
|
|
46
51
|
member: member,
|
|
47
52
|
invitation: invitation,
|
|
48
53
|
},
|
|
49
54
|
}),
|
|
50
|
-
baseURL:
|
|
55
|
+
baseURL: APP_URL,
|
|
51
56
|
emailAndPassword: {
|
|
52
57
|
enabled: true,
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
//
|
|
58
|
+
// Verification is required exactly when a verification email can be
|
|
59
|
+
// sent. Without a provider the link only reaches the server console,
|
|
60
|
+
// so requiring it would lock every new account out — in production
|
|
61
|
+
// as much as in development. `validateEnv` warns about that case.
|
|
62
|
+
requireEmailVerification: !(getEmailProvider() instanceof ConsoleProvider),
|
|
57
63
|
sendResetPassword: async ({ user, url }) => {
|
|
58
64
|
sendPasswordResetEmail({
|
|
59
65
|
to: user.email,
|
|
@@ -62,7 +68,6 @@ export const auth = betterAuth({
|
|
|
62
68
|
}).catch((err) => console.error("[Auth] Failed to send password reset email:", err));
|
|
63
69
|
},
|
|
64
70
|
},
|
|
65
|
-
// Email verification hook (EMAIL-04)
|
|
66
71
|
emailVerification: {
|
|
67
72
|
sendVerificationEmail: async ({ user, url }) => {
|
|
68
73
|
sendVerifyEmail({
|
|
@@ -75,7 +80,7 @@ export const auth = betterAuth({
|
|
|
75
80
|
autoSignInAfterVerification: true,
|
|
76
81
|
},
|
|
77
82
|
socialProviders: {
|
|
78
|
-
//
|
|
83
|
+
// Each OAuth provider is enabled only when its env vars are set.
|
|
79
84
|
...(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET
|
|
80
85
|
? {
|
|
81
86
|
google: {
|
|
@@ -84,7 +89,6 @@ export const auth = betterAuth({
|
|
|
84
89
|
},
|
|
85
90
|
}
|
|
86
91
|
: {}),
|
|
87
|
-
// GitHub OAuth - only enabled when env vars are configured
|
|
88
92
|
...(process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET
|
|
89
93
|
? {
|
|
90
94
|
github: {
|
|
@@ -95,55 +99,48 @@ export const auth = betterAuth({
|
|
|
95
99
|
: {}),
|
|
96
100
|
},
|
|
97
101
|
session: {
|
|
98
|
-
// Sessions expire after 7 days
|
|
99
102
|
expiresIn: 60 * 60 * 24 * 7,
|
|
100
|
-
//
|
|
103
|
+
// Refreshed at most daily, extending the expiry while in use.
|
|
101
104
|
updateAge: 60 * 60 * 24,
|
|
102
105
|
},
|
|
103
|
-
trustedOrigins:
|
|
104
|
-
// Database hooks for automatic workspace setup (WORK-01)
|
|
106
|
+
trustedOrigins: TRUSTED_ORIGINS,
|
|
105
107
|
databaseHooks: {
|
|
106
108
|
user: {
|
|
107
109
|
create: {
|
|
108
110
|
after: async (user) => {
|
|
109
|
-
//
|
|
111
|
+
// Provision the personal workspace.
|
|
110
112
|
try {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
headers: new Headers(),
|
|
113
|
+
const created = await auth.api.createOrganization({
|
|
114
|
+
// Deliberately no `headers`: the organization plugin throws
|
|
115
|
+
// UNAUTHORIZED when headers are present but carry no session,
|
|
116
|
+
// and an empty `new Headers()` counts as present. Omitting
|
|
117
|
+
// them takes the system path `body.userId` exists for.
|
|
117
118
|
body: {
|
|
118
119
|
name: `${user.name || "User"}'s Workspace`,
|
|
119
|
-
slug:
|
|
120
|
-
userId: user.id,
|
|
120
|
+
slug: personalWorkspaceSlug(user.email, user.id),
|
|
121
|
+
userId: user.id,
|
|
121
122
|
},
|
|
122
123
|
});
|
|
124
|
+
if (created) {
|
|
125
|
+
workspaceCreated({
|
|
126
|
+
workspaceId: created.id,
|
|
127
|
+
userId: user.id,
|
|
128
|
+
email: user.email,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
123
131
|
}
|
|
124
132
|
catch (error) {
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const orgs = await auth.api.listOrganizations({
|
|
133
|
-
headers: new Headers(),
|
|
134
|
-
});
|
|
135
|
-
if (orgs && orgs.length > 0) {
|
|
136
|
-
// Org already created by the other hook — not an error.
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
133
|
+
// The slug is derived from the user, so a racing provisioner
|
|
134
|
+
// loses on `organization.slug`'s unique index: the workspace
|
|
135
|
+
// exists, which is the outcome this hook wanted. Anything else
|
|
136
|
+
// is worth ops visibility, but never fails the registration.
|
|
137
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
138
|
+
if (!/already exists|duplicate|unique|slug/i.test(message)) {
|
|
139
|
+
console.error("[user.create hook] Failed to create workspace:", error);
|
|
139
140
|
}
|
|
140
|
-
// Log for ops visibility; do not throw (user registration succeeded)
|
|
141
|
-
console.error("[user.create hook] Failed to create workspace:", error);
|
|
142
141
|
}
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
// Acceptable for v0.2; consider transactional outbox for Phase 14.
|
|
146
|
-
const dashboardUrl = `${process.env.NEXT_PUBLIC_APP_URL || "http://localhost:4000"}/dashboard`;
|
|
142
|
+
// Fire-and-forget: no retry or outbox, a failure is only logged.
|
|
143
|
+
const dashboardUrl = `${APP_URL}/dashboard`;
|
|
147
144
|
sendWelcomeEmail({
|
|
148
145
|
to: user.email,
|
|
149
146
|
userName: user.name || user.email,
|
|
@@ -155,7 +152,7 @@ export const auth = betterAuth({
|
|
|
155
152
|
session: {
|
|
156
153
|
create: {
|
|
157
154
|
before: async (session) => {
|
|
158
|
-
//
|
|
155
|
+
// A soft-deleted user gets no session.
|
|
159
156
|
try {
|
|
160
157
|
const userRecord = await db
|
|
161
158
|
.select({ deletedAt: users.deletedAt })
|
|
@@ -168,23 +165,23 @@ export const auth = betterAuth({
|
|
|
168
165
|
}
|
|
169
166
|
catch (error) {
|
|
170
167
|
console.error("[session.create hook] Deleted user check failed:", error);
|
|
171
|
-
throw error;
|
|
168
|
+
throw error;
|
|
172
169
|
}
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
// headers through hook context if middleware layering is needed later.
|
|
170
|
+
// Set the active organization. Reads `member` directly because
|
|
171
|
+
// `/organization/list` resolves the user from a session, and this
|
|
172
|
+
// hook runs while that session is being created.
|
|
177
173
|
try {
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
174
|
+
const [membership] = await db
|
|
175
|
+
.select({ organizationId: member.organizationId })
|
|
176
|
+
.from(member)
|
|
177
|
+
.where(eq(member.userId, session.userId))
|
|
178
|
+
.orderBy(member.createdAt)
|
|
179
|
+
.limit(1);
|
|
180
|
+
if (membership) {
|
|
184
181
|
return {
|
|
185
182
|
data: {
|
|
186
183
|
...session,
|
|
187
|
-
activeOrganizationId:
|
|
184
|
+
activeOrganizationId: membership.organizationId,
|
|
188
185
|
},
|
|
189
186
|
};
|
|
190
187
|
}
|
|
@@ -199,44 +196,29 @@ export const auth = betterAuth({
|
|
|
199
196
|
},
|
|
200
197
|
plugins: [
|
|
201
198
|
organization({
|
|
202
|
-
// Allow all users to create organizations (will be plan-gated in Phase 15)
|
|
203
199
|
allowUserToCreateOrganization: async () => true,
|
|
204
|
-
// Generous default limit (will be plan-gated later)
|
|
205
200
|
organizationLimit: 5,
|
|
206
|
-
// Creator becomes owner (explicit for clarity)
|
|
207
201
|
creatorRole: "owner",
|
|
208
|
-
// Invitation email sending via Resend (EMAIL-06, replaces Phase 10 placeholder)
|
|
209
202
|
sendInvitationEmail: async (data) => {
|
|
210
|
-
const
|
|
203
|
+
const { acceptUrl, declineUrl } = invitationLinks(APP_URL, data.id);
|
|
211
204
|
sendInvitationEmail({
|
|
212
205
|
to: data.email,
|
|
213
206
|
inviterName: data.inviter?.user?.name || "A team member",
|
|
214
207
|
workspaceName: data.organization?.name || "a workspace",
|
|
215
208
|
role: data.role || "member",
|
|
216
|
-
acceptUrl
|
|
217
|
-
declineUrl
|
|
209
|
+
acceptUrl,
|
|
210
|
+
declineUrl,
|
|
218
211
|
}).catch((err) => console.error("[Auth] Failed to send invitation email:", err));
|
|
219
212
|
},
|
|
220
|
-
// Invitations expire after 7 days (matches TEAM-10)
|
|
221
213
|
invitationExpiresIn: 60 * 60 * 24 * 7,
|
|
222
214
|
}),
|
|
223
215
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
* `adminRoles` is deliberately a platform role and not a workspace
|
|
228
|
-
* one: workspace `owner` is per-tenant and every self-serve signup
|
|
229
|
-
* owns their own workspace, so gating anything cross-tenant on it
|
|
230
|
-
* grants it to everybody. `users.role` carries the platform role;
|
|
216
|
+
* Enabled for its impersonation endpoints, used by the console.
|
|
217
|
+
* `adminRoles` is a platform role, never a workspace one: every
|
|
218
|
+
* self-serve signup owns a workspace. `users.role` carries it;
|
|
231
219
|
* requirePlatformAdmin promotes from PLATFORM_ADMIN_EMAILS into it.
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* is measured in minutes, and a session inherited by whoever next
|
|
235
|
-
* uses that browser is the failure mode worth designing against.
|
|
236
|
-
*
|
|
237
|
-
* `allowImpersonatingAdmins` stays false: one platform admin
|
|
238
|
-
* cannot take over another's account, which is what keeps the
|
|
239
|
-
* audit trail meaningful.
|
|
220
|
+
* Sessions are capped at 30 minutes, and one admin cannot impersonate
|
|
221
|
+
* another, which keeps the audit trail meaningful.
|
|
240
222
|
*/
|
|
241
223
|
admin({
|
|
242
224
|
ac: accessControl,
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/team/errors.js
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* The team service (./service.ts) throws this for every failure it
|
|
5
|
-
* recognizes rather than returning an ad-hoc `{ success, error }`
|
|
6
|
-
* envelope — that shaping is a transport concern (a Server Action, a
|
|
7
|
-
* route handler) and belongs one layer up, alongside
|
|
8
|
-
* revalidatePath/Sentry/toast/i18n, none of which this package may
|
|
9
|
-
* depend on.
|
|
2
|
+
* Thrown for every failure the team service recognizes. Shaping it for a UI
|
|
3
|
+
* (a `{ success, error }` envelope, i18n, revalidation) is the transport's job.
|
|
10
4
|
*/
|
|
11
5
|
export class TeamServiceError extends Error {
|
|
12
6
|
constructor(code, message, options) {
|
|
@@ -15,13 +9,10 @@ export class TeamServiceError extends Error {
|
|
|
15
9
|
this.code = code;
|
|
16
10
|
this.meta = options?.meta;
|
|
17
11
|
if (options?.cause !== undefined) {
|
|
18
|
-
// ES2020 target predates the
|
|
19
|
-
// assign it directly so `instanceof Error` consumers (and Node's
|
|
20
|
-
// own error inspection) still see it.
|
|
12
|
+
// The ES2020 target predates the `cause` constructor option.
|
|
21
13
|
this.cause = options.cause;
|
|
22
14
|
}
|
|
23
|
-
//
|
|
24
|
-
// transpilation targets loses `instanceof`).
|
|
15
|
+
// Extending built-ins loses `instanceof` on some transpilation targets.
|
|
25
16
|
Object.setPrototypeOf(this, TeamServiceError.prototype);
|
|
26
17
|
}
|
|
27
18
|
}
|
package/dist/team/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/team/errors.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/team/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiCH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAIzC,YACE,IAA0B,EAC1B,OAAe,EACf,OAA0D;QAE1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC1B,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,6DAA6D;YAC5D,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,wEAAwE;QACxE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,KAAK,YAAY,gBAAgB,CAAC;AAC3C,CAAC"}
|
package/dist/team/schemas.js
CHANGED
|
@@ -1,27 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Team Management Validation Schemas
|
|
3
|
-
*
|
|
4
|
-
* Zod schemas for team invite and member management inputs, shared by
|
|
5
|
-
* the team service and its transports.
|
|
6
|
-
*
|
|
7
|
-
* (Ported from the product application’s team validation module — same
|
|
8
|
-
* semantics. Ignite's copy is retired at cutover.)
|
|
9
|
-
*/
|
|
1
|
+
/** Team inputs, shared by the team service and its transports. */
|
|
10
2
|
import { z } from "zod";
|
|
11
|
-
/**
|
|
12
|
-
* Invite Member Schema
|
|
13
|
-
* Email + role for inviting new team members
|
|
14
|
-
*/
|
|
15
3
|
export const inviteMemberSchema = z.object({
|
|
16
4
|
email: z.string().email("Please enter a valid email address"),
|
|
17
5
|
role: z.enum(["admin", "member"], {
|
|
18
|
-
|
|
6
|
+
// One message for a missing role and an unknown one: to the person
|
|
7
|
+
// filling in the form they are the same mistake.
|
|
8
|
+
error: "Please select a role",
|
|
19
9
|
}),
|
|
20
10
|
});
|
|
21
|
-
/**
|
|
22
|
-
* Update Role Schema
|
|
23
|
-
* For changing an existing member's role
|
|
24
|
-
*/
|
|
25
11
|
export const updateRoleSchema = z.object({
|
|
26
12
|
memberId: z.string().min(1),
|
|
27
13
|
role: z.enum(["admin", "member"]),
|
package/dist/team/schemas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/team/schemas.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/team/schemas.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAElE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,oCAAoC,CAAC;IAC7D,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE;QAChC,mEAAmE;QACnE,iDAAiD;QACjD,KAAK,EAAE,sBAAsB;KAC9B,CAAC;CACH,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;CAClC,CAAC,CAAC"}
|