@authcore/core 0.5.4 → 0.7.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/README.md +13 -2
- package/dist/auth.d.ts +17 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +65 -4
- package/dist/auth.js.map +1 -1
- package/dist/features/emailVerification.d.ts +1 -2
- package/dist/features/emailVerification.d.ts.map +1 -1
- package/dist/features/emailVerification.js.map +1 -1
- package/dist/features/invitation.d.ts +30 -0
- package/dist/features/invitation.d.ts.map +1 -0
- package/dist/features/invitation.js +66 -0
- package/dist/features/invitation.js.map +1 -0
- package/dist/features/passwordReset.d.ts +1 -2
- package/dist/features/passwordReset.d.ts.map +1 -1
- package/dist/features/passwordReset.js.map +1 -1
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +7 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/token.d.ts +1 -0
- package/dist/utils/token.d.ts.map +1 -1
- package/dist/utils/token.js.map +1 -1
- package/dist/utils/validation.d.ts +24 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +10 -0
- package/dist/utils/validation.js.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install @authcore/core
|
|
|
14
14
|
|
|
15
15
|
### `createAuth(config)`
|
|
16
16
|
|
|
17
|
-
The main factory that creates an auth instance with `register`, `login`, `verifyToken`, `verifyEmail`, `forgotPassword`, and `
|
|
17
|
+
The main factory that creates an auth instance with `register`, `login`, `verifyToken`, `verifyEmail`, `forgotPassword`, `resetPassword`, `invite`, and `acceptInvitation` methods.
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
20
|
import { createAuth } from '@authcore/core'
|
|
@@ -23,8 +23,9 @@ const auth = createAuth({
|
|
|
23
23
|
db: myDatabaseAdapter,
|
|
24
24
|
session: { strategy: 'jwt', secret: 'your-secret', expiresIn: '7d' },
|
|
25
25
|
email: { provider: myEmailAdapter, from: 'auth@example.com' },
|
|
26
|
-
features: ['emailVerification', 'passwordReset'],
|
|
26
|
+
features: ['emailVerification', 'passwordReset', 'invitation'],
|
|
27
27
|
password: { minLength: 8 },
|
|
28
|
+
rbac: { defaultRole: 'user' },
|
|
28
29
|
callbacks: {
|
|
29
30
|
onSignUp: (user) => { /* ... */ },
|
|
30
31
|
onSignIn: (user) => { /* ... */ },
|
|
@@ -106,9 +107,19 @@ import {
|
|
|
106
107
|
forgotPasswordSchema,
|
|
107
108
|
resetPasswordSchema,
|
|
108
109
|
verifyEmailSchema,
|
|
110
|
+
inviteSchema,
|
|
111
|
+
acceptInvitationSchema,
|
|
109
112
|
} from '@authcore/core'
|
|
110
113
|
```
|
|
111
114
|
|
|
115
|
+
### RBAC
|
|
116
|
+
|
|
117
|
+
Users have a `role` field (string). The default role for new registrations is `'user'`, configurable via `rbac.defaultRole`. The role is included in the JWT payload, so role checks don't need extra database lookups.
|
|
118
|
+
|
|
119
|
+
### Invitation
|
|
120
|
+
|
|
121
|
+
Enable the `'invitation'` feature to let authenticated users invite new users by email. The invited user receives a link to set their password and activate their account. Invitation tokens expire in 48 hours.
|
|
122
|
+
|
|
112
123
|
## License
|
|
113
124
|
|
|
114
125
|
[MIT](https://github.com/david-ouatedem/auth-core/blob/main/LICENSE)
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthCoreConfig, PublicUser } from '
|
|
1
|
+
import type { AuthCoreConfig, PublicUser } from '@authcore/types';
|
|
2
2
|
export declare class AuthError extends Error {
|
|
3
3
|
readonly code: string;
|
|
4
4
|
readonly statusCode: number;
|
|
@@ -53,6 +53,22 @@ export interface AuthCore {
|
|
|
53
53
|
* @throws AuthError if token is invalid or expired (400)
|
|
54
54
|
*/
|
|
55
55
|
resetPassword(input: unknown): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Invite a new user by email with an optional role.
|
|
58
|
+
* Creates the user record and sends an invitation email.
|
|
59
|
+
* @throws AuthError if user already exists (409) or feature not enabled
|
|
60
|
+
*/
|
|
61
|
+
invite(input: unknown, params: {
|
|
62
|
+
inviteUrl: string;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Accept an invitation by setting a password.
|
|
66
|
+
* @throws AuthError if token is invalid or expired (400)
|
|
67
|
+
*/
|
|
68
|
+
acceptInvitation(input: unknown): Promise<{
|
|
69
|
+
user: PublicUser;
|
|
70
|
+
token: string;
|
|
71
|
+
}>;
|
|
56
72
|
}
|
|
57
73
|
/**
|
|
58
74
|
* Create an AuthCore instance from the provided configuration.
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAwBjE,qBAAa,SAAU,SAAQ,KAAK;aAGhB,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM;gBAFlC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM;CAKrC;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAEtE;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAEnE;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAEtD;;;OAGG;IACH,qBAAqB,CAAC,MAAM,EAAE;QAC5B,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE,MAAM,CAAA;QACb,eAAe,EAAE,MAAM,CAAA;KACxB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjB;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE1C;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE7C;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5C;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpE;;;OAGG;IACH,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC/E;AAqBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CA8P3D"}
|
package/dist/auth.js
CHANGED
|
@@ -3,6 +3,8 @@ import { signJwt, verifyJwt } from './utils/token.js';
|
|
|
3
3
|
import { registerSchema, loginSchema, forgotPasswordSchema, resetPasswordSchema, verifyEmailSchema, } from './utils/validation.js';
|
|
4
4
|
import { createEmailVerification, verifyEmail as verifyEmailFeature, } from './features/emailVerification.js';
|
|
5
5
|
import { createPasswordReset, resetPassword as resetPasswordFeature, } from './features/passwordReset.js';
|
|
6
|
+
import { createInvitation, acceptInvitation as acceptInvitationFeature, } from './features/invitation.js';
|
|
7
|
+
import { inviteSchema, acceptInvitationSchema } from './utils/validation.js';
|
|
6
8
|
export class AuthError extends Error {
|
|
7
9
|
code;
|
|
8
10
|
statusCode;
|
|
@@ -18,6 +20,7 @@ function toPublicUser(user) {
|
|
|
18
20
|
id: user.id,
|
|
19
21
|
email: user.email,
|
|
20
22
|
emailVerified: user.emailVerified,
|
|
23
|
+
role: user.role,
|
|
21
24
|
createdAt: user.createdAt,
|
|
22
25
|
updatedAt: user.updatedAt,
|
|
23
26
|
};
|
|
@@ -38,12 +41,14 @@ function toPublicUser(user) {
|
|
|
38
41
|
* ```
|
|
39
42
|
*/
|
|
40
43
|
export function createAuth(config) {
|
|
41
|
-
const { db, session, email, features = [], password: pwConfig = {}, callbacks = {} } = config;
|
|
44
|
+
const { db, session, email, features = [], password: pwConfig = {}, callbacks = {}, rbac = {} } = config;
|
|
42
45
|
const saltRounds = pwConfig.saltRounds ?? 12;
|
|
43
46
|
const minPasswordLength = pwConfig.minLength ?? 8;
|
|
44
47
|
const expiresIn = session.expiresIn ?? '7d';
|
|
48
|
+
const defaultRole = rbac.defaultRole ?? 'user';
|
|
45
49
|
const hasEmailVerification = features.includes('emailVerification');
|
|
46
50
|
const hasPasswordReset = features.includes('passwordReset');
|
|
51
|
+
const hasInvitation = features.includes('invitation');
|
|
47
52
|
return {
|
|
48
53
|
async register(input) {
|
|
49
54
|
const schema = registerSchema(minPasswordLength);
|
|
@@ -57,9 +62,9 @@ export function createAuth(config) {
|
|
|
57
62
|
throw new AuthError('An account with this email already exists', 'EMAIL_EXISTS', 409);
|
|
58
63
|
}
|
|
59
64
|
const passwordHash = await hashPassword(password, saltRounds);
|
|
60
|
-
const user = await db.createUser({ email: userEmail, passwordHash });
|
|
65
|
+
const user = await db.createUser({ email: userEmail, passwordHash, role: defaultRole });
|
|
61
66
|
const publicUser = toPublicUser(user);
|
|
62
|
-
const token = signJwt({ sub: user.id, email: user.email }, session.secret, expiresIn);
|
|
67
|
+
const token = signJwt({ sub: user.id, email: user.email, role: user.role }, session.secret, expiresIn);
|
|
63
68
|
await callbacks.onSignUp?.(publicUser);
|
|
64
69
|
return { user: publicUser, token };
|
|
65
70
|
},
|
|
@@ -81,7 +86,7 @@ export function createAuth(config) {
|
|
|
81
86
|
throw new AuthError('Please verify your email address before signing in', 'EMAIL_NOT_VERIFIED', 403);
|
|
82
87
|
}
|
|
83
88
|
const publicUser = toPublicUser(user);
|
|
84
|
-
const token = signJwt({ sub: user.id, email: user.email }, session.secret, expiresIn);
|
|
89
|
+
const token = signJwt({ sub: user.id, email: user.email, role: user.role }, session.secret, expiresIn);
|
|
85
90
|
await callbacks.onSignIn?.(publicUser);
|
|
86
91
|
return { user: publicUser, token };
|
|
87
92
|
},
|
|
@@ -175,6 +180,62 @@ export function createAuth(config) {
|
|
|
175
180
|
throw new AuthError(message, 'INVALID_TOKEN', 400);
|
|
176
181
|
}
|
|
177
182
|
},
|
|
183
|
+
async invite(input, { inviteUrl }) {
|
|
184
|
+
if (!hasInvitation) {
|
|
185
|
+
throw new AuthError('invitation feature is not enabled', 'FEATURE_DISABLED', 500);
|
|
186
|
+
}
|
|
187
|
+
if (!email) {
|
|
188
|
+
throw new AuthError('Email provider is not configured', 'EMAIL_NOT_CONFIGURED', 500);
|
|
189
|
+
}
|
|
190
|
+
const parsed = inviteSchema.safeParse(input);
|
|
191
|
+
if (!parsed.success) {
|
|
192
|
+
throw new AuthError(parsed.error.errors[0]?.message ?? 'Validation failed', 'VALIDATION_ERROR', 400);
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
await createInvitation({
|
|
196
|
+
email: parsed.data.email,
|
|
197
|
+
role: parsed.data.role ?? defaultRole,
|
|
198
|
+
db,
|
|
199
|
+
emailProvider: email.provider,
|
|
200
|
+
from: email.from,
|
|
201
|
+
inviteUrl,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
if (err instanceof Error && err.message.includes('already exists')) {
|
|
206
|
+
throw new AuthError('A user with this email already exists', 'EMAIL_EXISTS', 409);
|
|
207
|
+
}
|
|
208
|
+
throw err;
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
async acceptInvitation(input) {
|
|
212
|
+
const schema = acceptInvitationSchema(minPasswordLength);
|
|
213
|
+
const parsed = schema.safeParse(input);
|
|
214
|
+
if (!parsed.success) {
|
|
215
|
+
throw new AuthError(parsed.error.errors[0]?.message ?? 'Validation failed', 'VALIDATION_ERROR', 400);
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
const { userId } = await acceptInvitationFeature({
|
|
219
|
+
rawToken: parsed.data.token,
|
|
220
|
+
newPassword: parsed.data.password,
|
|
221
|
+
db,
|
|
222
|
+
saltRounds,
|
|
223
|
+
});
|
|
224
|
+
const user = await db.findUserById(userId);
|
|
225
|
+
if (!user) {
|
|
226
|
+
throw new AuthError('User not found', 'USER_NOT_FOUND', 404);
|
|
227
|
+
}
|
|
228
|
+
const publicUser = toPublicUser(user);
|
|
229
|
+
const token = signJwt({ sub: user.id, email: user.email, role: user.role }, session.secret, expiresIn);
|
|
230
|
+
return { user: publicUser, token };
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
if (err instanceof AuthError)
|
|
234
|
+
throw err;
|
|
235
|
+
const message = err instanceof Error ? err.message : 'Invalid token';
|
|
236
|
+
throw new AuthError(message, 'INVALID_TOKEN', 400);
|
|
237
|
+
}
|
|
238
|
+
},
|
|
178
239
|
};
|
|
179
240
|
}
|
|
180
241
|
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { DatabaseAdapter } from '
|
|
2
|
-
import type { EmailAdapter } from '../adapters/email.interface.js';
|
|
1
|
+
import type { DatabaseAdapter, EmailAdapter } from '@authcore/types';
|
|
3
2
|
/**
|
|
4
3
|
* Create an email verification token and send the verification email.
|
|
5
4
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emailVerification.d.ts","sourceRoot":"","sources":["../../src/features/emailVerification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"emailVerification.d.ts","sourceRoot":"","sources":["../../src/features/emailVerification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAS,MAAM,iBAAiB,CAAA;AAK3E;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,eAAe,CAAA;IACnB,aAAa,EAAE,YAAY,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,MAAM,CAAA;CACxB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BlB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,EAAE,EAAE,eAAe,CAAA;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emailVerification.js","sourceRoot":"","sources":["../../src/features/emailVerification.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"emailVerification.js","sourceRoot":"","sources":["../../src/features/emailVerification.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElE,MAAM,yBAAyB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,WAAW;AAEjE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAO7C;IACC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,MAAM,CAAA;IAE1E,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAA;IACtC,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;IAEvC,MAAM,EAAE,CAAC,WAAW,CAAC;QACnB,MAAM;QACN,IAAI,EAAE,oBAAoB;QAC1B,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,yBAAyB,CAAC;KAC5D,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,GAAG,eAAe,UAAU,QAAQ,EAAE,CAAA;IAEnD,MAAM,aAAa,CAAC,IAAI,CAAC;QACvB,IAAI;QACJ,EAAE,EAAE,KAAK;QACT,OAAO,EAAE,2BAA2B;QACpC,IAAI,EAAE;;;oBAGU,IAAI,KAAK,IAAI;;;KAG5B;QACD,IAAI,EAAE,yCAAyC,IAAI,oCAAoC;KACxF,CAAC,CAAA;IAEF,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAGjC;IACC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,MAAM,CAAA;IAE/B,MAAM,WAAW,GAAiB,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAA;IAEpF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IAC1D,CAAC;IAED,IAAI,WAAW,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QACpC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IAChE,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DatabaseAdapter, EmailAdapter } from '@authcore/types';
|
|
2
|
+
/**
|
|
3
|
+
* Create an invitation for a new user.
|
|
4
|
+
* Creates the user record (with no usable password) and sends an invitation email.
|
|
5
|
+
*
|
|
6
|
+
* @throws Error if a user with the given email already exists
|
|
7
|
+
*/
|
|
8
|
+
export declare function createInvitation(params: {
|
|
9
|
+
email: string;
|
|
10
|
+
role: string;
|
|
11
|
+
db: DatabaseAdapter;
|
|
12
|
+
emailProvider: EmailAdapter;
|
|
13
|
+
from: string;
|
|
14
|
+
inviteUrl: string;
|
|
15
|
+
}): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Accept an invitation by setting the user's password.
|
|
18
|
+
* Marks the user's email as verified and deletes the invitation token.
|
|
19
|
+
*
|
|
20
|
+
* @throws Error if the token is invalid or expired
|
|
21
|
+
*/
|
|
22
|
+
export declare function acceptInvitation(params: {
|
|
23
|
+
rawToken: string;
|
|
24
|
+
newPassword: string;
|
|
25
|
+
db: DatabaseAdapter;
|
|
26
|
+
saltRounds?: number;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
userId: string;
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=invitation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invitation.d.ts","sourceRoot":"","sources":["../../src/features/invitation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAe,MAAM,iBAAiB,CAAA;AAMjF;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,eAAe,CAAA;IACnB,aAAa,EAAE,YAAY,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,EAAE,EAAE,eAAe,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAmB9B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { generateOpaqueToken, hashToken } from '../utils/token.js';
|
|
2
|
+
import { hashPassword } from '../utils/password.js';
|
|
3
|
+
const INVITATION_TTL_MS = 48 * 60 * 60 * 1000; // 48 hours
|
|
4
|
+
/**
|
|
5
|
+
* Create an invitation for a new user.
|
|
6
|
+
* Creates the user record (with no usable password) and sends an invitation email.
|
|
7
|
+
*
|
|
8
|
+
* @throws Error if a user with the given email already exists
|
|
9
|
+
*/
|
|
10
|
+
export async function createInvitation(params) {
|
|
11
|
+
const { email, role, db, emailProvider, from, inviteUrl } = params;
|
|
12
|
+
const existing = await db.findUserByEmail(email);
|
|
13
|
+
if (existing) {
|
|
14
|
+
throw new Error('A user with this email already exists');
|
|
15
|
+
}
|
|
16
|
+
// Create user with a placeholder password hash (cannot be used to login)
|
|
17
|
+
const user = await db.createUser({
|
|
18
|
+
email,
|
|
19
|
+
passwordHash: '!INVITED_NO_PASSWORD',
|
|
20
|
+
role,
|
|
21
|
+
});
|
|
22
|
+
const rawToken = generateOpaqueToken();
|
|
23
|
+
const hashedToken = hashToken(rawToken);
|
|
24
|
+
await db.createToken({
|
|
25
|
+
userId: user.id,
|
|
26
|
+
type: 'INVITATION',
|
|
27
|
+
token: hashedToken,
|
|
28
|
+
expiresAt: new Date(Date.now() + INVITATION_TTL_MS),
|
|
29
|
+
});
|
|
30
|
+
const link = `${inviteUrl}?token=${rawToken}`;
|
|
31
|
+
await emailProvider.send({
|
|
32
|
+
from,
|
|
33
|
+
to: email,
|
|
34
|
+
subject: 'You have been invited',
|
|
35
|
+
html: `
|
|
36
|
+
<p>Hello,</p>
|
|
37
|
+
<p>You have been invited to create an account. Click the link below to set your password:</p>
|
|
38
|
+
<p><a href="${link}">${link}</a></p>
|
|
39
|
+
<p>This link expires in 48 hours.</p>
|
|
40
|
+
`,
|
|
41
|
+
text: `You have been invited. Set your password by visiting: ${link}\n\nThis link expires in 48 hours.`,
|
|
42
|
+
});
|
|
43
|
+
return rawToken;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Accept an invitation by setting the user's password.
|
|
47
|
+
* Marks the user's email as verified and deletes the invitation token.
|
|
48
|
+
*
|
|
49
|
+
* @throws Error if the token is invalid or expired
|
|
50
|
+
*/
|
|
51
|
+
export async function acceptInvitation(params) {
|
|
52
|
+
const { rawToken, newPassword, db, saltRounds } = params;
|
|
53
|
+
const tokenRecord = await db.findToken(rawToken, 'INVITATION');
|
|
54
|
+
if (!tokenRecord) {
|
|
55
|
+
throw new Error('Invalid or expired invitation token');
|
|
56
|
+
}
|
|
57
|
+
if (tokenRecord.expiresAt < new Date()) {
|
|
58
|
+
await db.deleteToken(tokenRecord.id);
|
|
59
|
+
throw new Error('Invalid or expired invitation token');
|
|
60
|
+
}
|
|
61
|
+
const passwordHash = await hashPassword(newPassword, saltRounds);
|
|
62
|
+
await db.updateUser(tokenRecord.userId, { passwordHash, emailVerified: true });
|
|
63
|
+
await db.deleteToken(tokenRecord.id);
|
|
64
|
+
return { userId: tokenRecord.userId };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=invitation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invitation.js","sourceRoot":"","sources":["../../src/features/invitation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,WAAW;AAEzD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAOtC;IACC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IAElE,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IAChD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IAC1D,CAAC;IAED,yEAAyE;IACzE,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC;QAC/B,KAAK;QACL,YAAY,EAAE,sBAAsB;QACpC,IAAI;KACL,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAA;IACtC,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;IAEvC,MAAM,EAAE,CAAC,WAAW,CAAC;QACnB,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,CAAC;KACpD,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,GAAG,SAAS,UAAU,QAAQ,EAAE,CAAA;IAE7C,MAAM,aAAa,CAAC,IAAI,CAAC;QACvB,IAAI;QACJ,EAAE,EAAE,KAAK;QACT,OAAO,EAAE,uBAAuB;QAChC,IAAI,EAAE;;;oBAGU,IAAI,KAAK,IAAI;;KAE5B;QACD,IAAI,EAAE,yDAAyD,IAAI,oCAAoC;KACxG,CAAC,CAAA;IAEF,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAKtC;IACC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;IAExD,MAAM,WAAW,GAAiB,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IAE5E,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;IACxD,CAAC;IAED,IAAI,WAAW,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QACpC,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;IACxD,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;IAChE,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IAC9E,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IAEpC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,CAAA;AACvC,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { DatabaseAdapter } from '
|
|
2
|
-
import type { EmailAdapter } from '../adapters/email.interface.js';
|
|
1
|
+
import type { DatabaseAdapter, EmailAdapter } from '@authcore/types';
|
|
3
2
|
/**
|
|
4
3
|
* Initiate a password reset flow.
|
|
5
4
|
* Always returns successfully even if the email is not found — prevents email enumeration.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passwordReset.d.ts","sourceRoot":"","sources":["../../src/features/passwordReset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"passwordReset.d.ts","sourceRoot":"","sources":["../../src/features/passwordReset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAS,MAAM,iBAAiB,CAAA;AAM3E;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,eAAe,CAAA;IACnB,aAAa,EAAE,YAAY,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgChB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,EAAE,EAAE,eAAe,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passwordReset.js","sourceRoot":"","sources":["../../src/features/passwordReset.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"passwordReset.js","sourceRoot":"","sources":["../../src/features/passwordReset.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,SAAS;AAEtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAMzC;IACC,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAE3D,8DAA8D;IAC9D,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;IAC5C,IAAI,CAAC,IAAI;QAAE,OAAM;IAEjB,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAA;IACtC,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;IAEvC,MAAM,EAAE,CAAC,WAAW,CAAC;QACnB,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,WAAW;QAClB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,qBAAqB,CAAC;KACxD,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,GAAG,QAAQ,UAAU,QAAQ,EAAE,CAAA;IAE5C,MAAM,aAAa,CAAC,IAAI,CAAC;QACvB,IAAI;QACJ,EAAE,EAAE,KAAK;QACT,OAAO,EAAE,qBAAqB;QAC9B,IAAI,EAAE;;;oBAGU,IAAI,KAAK,IAAI;;;KAG5B;QACD,IAAI,EAAE,oCAAoC,IAAI,kCAAkC;KACjF,CAAC,CAAA;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAKnC;IACC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;IAExD,MAAM,WAAW,GAAiB,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAA;IAEhF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAC;IAED,IAAI,WAAW,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QACpC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;IAChE,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,CAAC,CAAA;IACzD,MAAM,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AACtC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
export type { User, Token, TokenType, CreateUserInput, CreateTokenInput, PublicUser, SessionConfig, EmailConfig, AuthCallbacks, AuthCoreConfig, } from './types.js';
|
|
2
|
-
export type { DatabaseAdapter } from './adapters/database.interface.js';
|
|
3
|
-
export type { EmailAdapter } from './adapters/email.interface.js';
|
|
4
1
|
export { hashPassword, verifyPassword } from './utils/password.js';
|
|
5
2
|
export { generateOpaqueToken, hashToken, safeCompareTokens, signJwt, verifyJwt, } from './utils/token.js';
|
|
6
3
|
export type { JwtPayload } from './utils/token.js';
|
|
7
|
-
export { registerSchema, loginSchema, forgotPasswordSchema, resetPasswordSchema, verifyEmailSchema, } from './utils/validation.js';
|
|
8
|
-
export type { RegisterInput, LoginInput, ForgotPasswordInput, ResetPasswordInput, VerifyEmailInput, } from './utils/validation.js';
|
|
4
|
+
export { registerSchema, loginSchema, forgotPasswordSchema, resetPasswordSchema, verifyEmailSchema, inviteSchema, acceptInvitationSchema, } from './utils/validation.js';
|
|
5
|
+
export type { RegisterInput, LoginInput, ForgotPasswordInput, ResetPasswordInput, VerifyEmailInput, InviteInput, AcceptInvitationInput, } from './utils/validation.js';
|
|
9
6
|
export { createEmailVerification, verifyEmail } from './features/emailVerification.js';
|
|
10
7
|
export { createPasswordReset, resetPassword } from './features/passwordReset.js';
|
|
8
|
+
export { createInvitation, acceptInvitation } from './features/invitation.js';
|
|
11
9
|
export { createAuth, AuthError } from './auth.js';
|
|
12
10
|
export type { AuthCore } from './auth.js';
|
|
11
|
+
export * from '@authcore/types';
|
|
13
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,SAAS,GACV,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EACL,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,GACvB,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EACV,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,EACX,qBAAqB,GACtB,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AACtF,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAChF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAG7E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACjD,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEzC,cAAc,iBAAiB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// Utilities
|
|
2
2
|
export { hashPassword, verifyPassword } from './utils/password.js';
|
|
3
3
|
export { generateOpaqueToken, hashToken, safeCompareTokens, signJwt, verifyJwt, } from './utils/token.js';
|
|
4
|
-
export { registerSchema, loginSchema, forgotPasswordSchema, resetPasswordSchema, verifyEmailSchema, } from './utils/validation.js';
|
|
4
|
+
export { registerSchema, loginSchema, forgotPasswordSchema, resetPasswordSchema, verifyEmailSchema, inviteSchema, acceptInvitationSchema, } from './utils/validation.js';
|
|
5
5
|
// Features
|
|
6
6
|
export { createEmailVerification, verifyEmail } from './features/emailVerification.js';
|
|
7
7
|
export { createPasswordReset, resetPassword } from './features/passwordReset.js';
|
|
8
|
+
export { createInvitation, acceptInvitation } from './features/invitation.js';
|
|
8
9
|
// Auth factory
|
|
9
10
|
export { createAuth, AuthError } from './auth.js';
|
|
11
|
+
export * from '@authcore/types';
|
|
10
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY;AACZ,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,SAAS,GACV,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,GACvB,MAAM,uBAAuB,CAAA;AAW9B,WAAW;AACX,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AACtF,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAChF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE7E,eAAe;AACf,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAGjD,cAAc,iBAAiB,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* Core domain types for AuthCore.
|
|
3
3
|
* These are the canonical shapes that adapters must produce/consume.
|
|
4
4
|
*/
|
|
5
|
-
export type TokenType = 'EMAIL_VERIFICATION' | 'PASSWORD_RESET' | 'SESSION';
|
|
5
|
+
export type TokenType = 'EMAIL_VERIFICATION' | 'PASSWORD_RESET' | 'SESSION' | 'INVITATION';
|
|
6
6
|
/** A user record as stored in the database. */
|
|
7
7
|
export interface User {
|
|
8
8
|
id: string;
|
|
9
9
|
email: string;
|
|
10
10
|
passwordHash: string;
|
|
11
11
|
emailVerified: boolean;
|
|
12
|
+
role: string;
|
|
12
13
|
createdAt: Date;
|
|
13
14
|
updatedAt: Date;
|
|
14
15
|
}
|
|
@@ -26,6 +27,7 @@ export interface Token {
|
|
|
26
27
|
export interface CreateUserInput {
|
|
27
28
|
email: string;
|
|
28
29
|
passwordHash: string;
|
|
30
|
+
role?: string;
|
|
29
31
|
}
|
|
30
32
|
/** Input shape for creating a new token. */
|
|
31
33
|
export interface CreateTokenInput {
|
|
@@ -60,12 +62,15 @@ export interface AuthCoreConfig {
|
|
|
60
62
|
db: import('./adapters/database.interface.js').DatabaseAdapter;
|
|
61
63
|
session: SessionConfig;
|
|
62
64
|
email?: EmailConfig;
|
|
63
|
-
features?: Array<'emailVerification' | 'passwordReset'>;
|
|
65
|
+
features?: Array<'emailVerification' | 'passwordReset' | 'invitation'>;
|
|
64
66
|
mode?: 'api' | 'monorepo' | 'auto';
|
|
65
67
|
password?: {
|
|
66
68
|
minLength?: number;
|
|
67
69
|
saltRounds?: number;
|
|
68
70
|
};
|
|
71
|
+
rbac?: {
|
|
72
|
+
defaultRole?: string;
|
|
73
|
+
};
|
|
69
74
|
callbacks?: AuthCallbacks;
|
|
70
75
|
}
|
|
71
76
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GAAG,oBAAoB,GAAG,gBAAgB,GAAG,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GAAG,oBAAoB,GAAG,gBAAgB,GAAG,SAAS,GAAG,YAAY,CAAA;AAE1F,+CAA+C;AAC/C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,OAAO,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,uFAAuF;AACvF,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,SAAS,CAAA;IACf,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,2CAA2C;AAC3C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,SAAS,CAAA;IACf,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,6DAA6D;AAC7D,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;AAEnD,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,KAAK,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wCAAwC;AACxC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,+BAA+B,EAAE,YAAY,CAAA;IAC9D,IAAI,EAAE,MAAM,CAAA;CACb;AAED,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrD,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7D;AAED,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,kCAAkC,EAAE,eAAe,CAAA;IAC9D,OAAO,EAAE,aAAa,CAAA;IACtB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,mBAAmB,GAAG,eAAe,GAAG,YAAY,CAAC,CAAA;IACtE,IAAI,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,MAAM,CAAA;IAClC,QAAQ,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;IACD,IAAI,CAAC,EAAE;QACL,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,SAAS,CAAC,EAAE,aAAa,CAAA;CAC1B"}
|
package/dist/utils/token.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAK/D;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,KAAK,CAAC,EACxC,MAAM,EAAE,MAAM,EACd,SAAS,SAAO,GACf,MAAM,CAIR;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQ1E"}
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAK/D;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,KAAK,CAAC,EACxC,MAAM,EAAE,MAAM,EACd,SAAS,SAAO,GACf,MAAM,CAIR;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQ1E"}
|
package/dist/utils/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACtE,OAAO,GAAG,MAAM,cAAc,CAAA;AAE9B;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AACxC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAS,EAAE,CAAS;IACpD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IACnC,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACpC,CAAC;
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/utils/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AACtE,OAAO,GAAG,MAAM,cAAc,CAAA;AAE9B;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AACxC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAS,EAAE,CAAS;IACpD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IACnC,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACpC,CAAC;AAUD;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CACrB,OAAwC,EACxC,MAAc,EACd,SAAS,GAAG,IAAI;IAEhB,mFAAmF;IACnF,MAAM,OAAO,GAAG,EAAE,SAAS,EAAE,OAAgB,EAAE,SAAS,EAAE,CAAA;IAC1D,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAA0B,CAAC,CAAA;AAC9D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,MAAc;IACrD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACpE,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QAC5C,OAAO,OAAqB,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
|
|
@@ -48,9 +48,33 @@ export declare const verifyEmailSchema: z.ZodObject<{
|
|
|
48
48
|
}, {
|
|
49
49
|
token: string;
|
|
50
50
|
}>;
|
|
51
|
+
/** Schema for POST /invite */
|
|
52
|
+
export declare const inviteSchema: z.ZodObject<{
|
|
53
|
+
email: z.ZodString;
|
|
54
|
+
role: z.ZodOptional<z.ZodString>;
|
|
55
|
+
}, "strip", z.ZodTypeAny, {
|
|
56
|
+
email: string;
|
|
57
|
+
role?: string | undefined;
|
|
58
|
+
}, {
|
|
59
|
+
email: string;
|
|
60
|
+
role?: string | undefined;
|
|
61
|
+
}>;
|
|
62
|
+
/** Schema for POST /accept-invitation */
|
|
63
|
+
export declare const acceptInvitationSchema: (minPasswordLength?: number) => z.ZodObject<{
|
|
64
|
+
token: z.ZodString;
|
|
65
|
+
password: z.ZodString;
|
|
66
|
+
}, "strip", z.ZodTypeAny, {
|
|
67
|
+
password: string;
|
|
68
|
+
token: string;
|
|
69
|
+
}, {
|
|
70
|
+
password: string;
|
|
71
|
+
token: string;
|
|
72
|
+
}>;
|
|
51
73
|
export type RegisterInput = z.infer<ReturnType<typeof registerSchema>>;
|
|
52
74
|
export type LoginInput = z.infer<typeof loginSchema>;
|
|
53
75
|
export type ForgotPasswordInput = z.infer<typeof forgotPasswordSchema>;
|
|
54
76
|
export type ResetPasswordInput = z.infer<ReturnType<typeof resetPasswordSchema>>;
|
|
55
77
|
export type VerifyEmailInput = z.infer<typeof verifyEmailSchema>;
|
|
78
|
+
export type InviteInput = z.infer<typeof inviteSchema>;
|
|
79
|
+
export type AcceptInvitationInput = z.infer<ReturnType<typeof acceptInvitationSchema>>;
|
|
56
80
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAUvB,gCAAgC;AAChC,eAAO,MAAM,cAAc,GAAI,0BAAqB;;;;;;;;;EAIhD,CAAA;AAEJ,6BAA6B;AAC7B,eAAO,MAAM,WAAW;;;;;;;;;EAGtB,CAAA;AAEF,uCAAuC;AACvC,eAAO,MAAM,oBAAoB;;;;;;EAE/B,CAAA;AAEF,sCAAsC;AACtC,eAAO,MAAM,mBAAmB,GAAI,0BAAqB;;;;;;;;;EAIrD,CAAA;AAEJ,oCAAoC;AACpC,eAAO,MAAM,iBAAiB;;;;;;EAE5B,CAAA;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAA;AACtE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AACpD,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAA;AAChF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAUvB,gCAAgC;AAChC,eAAO,MAAM,cAAc,GAAI,0BAAqB;;;;;;;;;EAIhD,CAAA;AAEJ,6BAA6B;AAC7B,eAAO,MAAM,WAAW;;;;;;;;;EAGtB,CAAA;AAEF,uCAAuC;AACvC,eAAO,MAAM,oBAAoB;;;;;;EAE/B,CAAA;AAEF,sCAAsC;AACtC,eAAO,MAAM,mBAAmB,GAAI,0BAAqB;;;;;;;;;EAIrD,CAAA;AAEJ,oCAAoC;AACpC,eAAO,MAAM,iBAAiB;;;;;;EAE5B,CAAA;AAEF,8BAA8B;AAC9B,eAAO,MAAM,YAAY;;;;;;;;;EAGvB,CAAA;AAEF,yCAAyC;AACzC,eAAO,MAAM,sBAAsB,GAAI,0BAAqB;;;;;;;;;EAIxD,CAAA;AAEJ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAA;AACtE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AACpD,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAA;AAChF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAChE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AACtD,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAA"}
|
package/dist/utils/validation.js
CHANGED
|
@@ -27,4 +27,14 @@ export const resetPasswordSchema = (minPasswordLength = 8) => z.object({
|
|
|
27
27
|
export const verifyEmailSchema = z.object({
|
|
28
28
|
token: z.string().min(1, 'Token is required'),
|
|
29
29
|
});
|
|
30
|
+
/** Schema for POST /invite */
|
|
31
|
+
export const inviteSchema = z.object({
|
|
32
|
+
email: emailSchema,
|
|
33
|
+
role: z.string().min(1).optional(),
|
|
34
|
+
});
|
|
35
|
+
/** Schema for POST /accept-invitation */
|
|
36
|
+
export const acceptInvitationSchema = (minPasswordLength = 8) => z.object({
|
|
37
|
+
token: z.string().min(1, 'Token is required'),
|
|
38
|
+
password: passwordSchema(minPasswordLength),
|
|
39
|
+
});
|
|
30
40
|
//# sourceMappingURL=validation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;AAE7D,MAAM,cAAc,GAAG,CAAC,SAAiB,EAAE,EAAE,CAC3C,CAAC;KACE,MAAM,EAAE;KACR,GAAG,CAAC,SAAS,EAAE,6BAA6B,SAAS,aAAa,CAAC;KACnE,GAAG,CAAC,EAAE,EAAE,wCAAwC,CAAC,CAAA,CAAC,aAAa;AAEpE,gCAAgC;AAChC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE,EAAE,CACtD,CAAC,CAAC,MAAM,CAAC;IACP,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC;CAC5C,CAAC,CAAA;AAEJ,6BAA6B;AAC7B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,sBAAsB,CAAC;CACpD,CAAC,CAAA;AAEF,uCAAuC;AACvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,WAAW;CACnB,CAAC,CAAA;AAEF,sCAAsC;AACtC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE,EAAE,CAC3D,CAAC,CAAC,MAAM,CAAC;IACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC;IAC7C,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC;CAC5C,CAAC,CAAA;AAEJ,oCAAoC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC;CAC9C,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAA;AAE7D,MAAM,cAAc,GAAG,CAAC,SAAiB,EAAE,EAAE,CAC3C,CAAC;KACE,MAAM,EAAE;KACR,GAAG,CAAC,SAAS,EAAE,6BAA6B,SAAS,aAAa,CAAC;KACnE,GAAG,CAAC,EAAE,EAAE,wCAAwC,CAAC,CAAA,CAAC,aAAa;AAEpE,gCAAgC;AAChC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE,EAAE,CACtD,CAAC,CAAC,MAAM,CAAC;IACP,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC;CAC5C,CAAC,CAAA;AAEJ,6BAA6B;AAC7B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,sBAAsB,CAAC;CACpD,CAAC,CAAA;AAEF,uCAAuC;AACvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,WAAW;CACnB,CAAC,CAAA;AAEF,sCAAsC;AACtC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE,EAAE,CAC3D,CAAC,CAAC,MAAM,CAAC;IACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC;IAC7C,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC;CAC5C,CAAC,CAAA;AAEJ,oCAAoC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC;CAC9C,CAAC,CAAA;AAEF,8BAA8B;AAC9B,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAA;AAEF,yCAAyC;AACzC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE,EAAE,CAC9D,CAAC,CAAC,MAAM,CAAC;IACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC;IAC7C,QAAQ,EAAE,cAAc,CAAC,iBAAiB,CAAC;CAC5C,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@authcore/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Framework-agnostic authentication core for AuthCore",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "David Ouatedem",
|
|
@@ -35,10 +35,11 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"bcryptjs": "^2.4.3",
|
|
37
37
|
"jsonwebtoken": "^9.0.2",
|
|
38
|
-
"zod": "^3.23.0"
|
|
38
|
+
"zod": "^3.23.0",
|
|
39
|
+
"@authcore/types": "^0.7.0"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@types/bcryptjs": "^2.4.
|
|
42
|
+
"@types/bcryptjs": "^2.4.3",
|
|
42
43
|
"@types/jsonwebtoken": "^9.0.6",
|
|
43
44
|
"@types/node": "^20.0.0",
|
|
44
45
|
"typescript": "^5.4.0",
|