@amtarc/auth-utils 1.0.1
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/LICENSE +21 -0
- package/README.md +82 -0
- package/dist/chunk-5MVLFEZI.js +67 -0
- package/dist/chunk-5MVLFEZI.js.map +1 -0
- package/dist/chunk-5XQQYIDO.js +3 -0
- package/dist/chunk-5XQQYIDO.js.map +1 -0
- package/dist/chunk-LBCZ2NQO.cjs +4 -0
- package/dist/chunk-LBCZ2NQO.cjs.map +1 -0
- package/dist/chunk-MAVNKELK.js +65 -0
- package/dist/chunk-MAVNKELK.js.map +1 -0
- package/dist/chunk-NW5NFB77.cjs +71 -0
- package/dist/chunk-NW5NFB77.cjs.map +1 -0
- package/dist/chunk-OIQMYYPZ.cjs +4 -0
- package/dist/chunk-OIQMYYPZ.cjs.map +1 -0
- package/dist/chunk-RGDYDO4P.cjs +74 -0
- package/dist/chunk-RGDYDO4P.cjs.map +1 -0
- package/dist/chunk-USPZICST.js +3 -0
- package/dist/chunk-USPZICST.js.map +1 -0
- package/dist/cookies/index.cjs +6 -0
- package/dist/cookies/index.cjs.map +1 -0
- package/dist/cookies/index.d.cts +2 -0
- package/dist/cookies/index.d.ts +2 -0
- package/dist/cookies/index.js +3 -0
- package/dist/cookies/index.js.map +1 -0
- package/dist/errors/index.cjs +40 -0
- package/dist/errors/index.cjs.map +1 -0
- package/dist/errors/index.d.cts +52 -0
- package/dist/errors/index.d.ts +52 -0
- package/dist/errors/index.js +3 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/guards/index.cjs +6 -0
- package/dist/guards/index.cjs.map +1 -0
- package/dist/guards/index.d.cts +2 -0
- package/dist/guards/index.d.ts +2 -0
- package/dist/guards/index.js +3 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/index-Bg3pYjD_.d.cts +138 -0
- package/dist/index-Bg3pYjD_.d.ts +138 -0
- package/dist/index.cjs +57 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/session/index.cjs +21 -0
- package/dist/session/index.cjs.map +1 -0
- package/dist/session/index.d.cts +1 -0
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.js +4 -0
- package/dist/session/index.js.map +1 -0
- package/package.json +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 amtarc
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @amtarc/auth-utils
|
|
2
|
+
|
|
3
|
+
> Core authentication and session management utilities
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @amtarc/auth-utils
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- ✅ Session creation and validation
|
|
14
|
+
- ✅ Session guards and middleware
|
|
15
|
+
- ✅ Framework-agnostic design
|
|
16
|
+
- ✅ TypeScript-first with full type safety
|
|
17
|
+
- ✅ Zero runtime dependencies
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { createSession, validateSession, requireSession } from '@amtarc/auth-utils';
|
|
23
|
+
|
|
24
|
+
// Create a session
|
|
25
|
+
const session = createSession('user-123', {
|
|
26
|
+
expiresIn: 1000 * 60 * 60 * 24, // 24 hours
|
|
27
|
+
idleTimeout: 1000 * 60 * 30, // 30 minutes
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Validate a session
|
|
31
|
+
const validation = validateSession(session);
|
|
32
|
+
if (!validation.valid) {
|
|
33
|
+
console.error('Session invalid:', validation.reason);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Use as a guard
|
|
37
|
+
const getSession = () => getCurrentSession(); // Your session retrieval logic
|
|
38
|
+
const guard = requireSession(getSession);
|
|
39
|
+
|
|
40
|
+
const handler = guard(async (session) => {
|
|
41
|
+
return { userId: session.userId };
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## API Reference
|
|
46
|
+
|
|
47
|
+
### `createSession(userId, options)`
|
|
48
|
+
|
|
49
|
+
Creates a new session for a user.
|
|
50
|
+
|
|
51
|
+
**Parameters:**
|
|
52
|
+
- `userId` (string): The user ID
|
|
53
|
+
- `options` (SessionOptions): Configuration options
|
|
54
|
+
- `expiresIn` (number): Session lifetime in milliseconds (default: 7 days)
|
|
55
|
+
- `idleTimeout` (number): Idle timeout in milliseconds
|
|
56
|
+
- `fingerprint` (boolean): Enable session fingerprinting
|
|
57
|
+
|
|
58
|
+
**Returns:** `Session<TUser>`
|
|
59
|
+
|
|
60
|
+
### `validateSession(session, options)`
|
|
61
|
+
|
|
62
|
+
Validates a session against expiration and idle timeout rules.
|
|
63
|
+
|
|
64
|
+
**Parameters:**
|
|
65
|
+
- `session` (Session): The session to validate
|
|
66
|
+
- `options` (SessionOptions): Validation options
|
|
67
|
+
|
|
68
|
+
**Returns:** `ValidationResult`
|
|
69
|
+
|
|
70
|
+
### `requireSession(getSession, options)`
|
|
71
|
+
|
|
72
|
+
Creates a guard that requires a valid session.
|
|
73
|
+
|
|
74
|
+
**Parameters:**
|
|
75
|
+
- `getSession` (() => Session | Promise<Session | null>): Function to retrieve session
|
|
76
|
+
- `options` (SessionOptions): Session validation options
|
|
77
|
+
|
|
78
|
+
**Returns:** Guard function
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { SessionExpiredError } from './chunk-MAVNKELK.js';
|
|
2
|
+
import { randomBytes } from 'crypto';
|
|
3
|
+
|
|
4
|
+
function generateSessionId() {
|
|
5
|
+
const timestamp = Date.now().toString(36);
|
|
6
|
+
const randomPart = randomBytes(16).toString("hex");
|
|
7
|
+
return `session_${timestamp}_${randomPart}`;
|
|
8
|
+
}
|
|
9
|
+
function createSession(userId, options = {}) {
|
|
10
|
+
const now = /* @__PURE__ */ new Date();
|
|
11
|
+
const expiresIn = options.expiresIn ?? 1e3 * 60 * 60 * 24 * 7;
|
|
12
|
+
const session = {
|
|
13
|
+
id: generateSessionId(),
|
|
14
|
+
userId,
|
|
15
|
+
expiresAt: new Date(now.getTime() + expiresIn),
|
|
16
|
+
createdAt: now,
|
|
17
|
+
lastActivityAt: now
|
|
18
|
+
};
|
|
19
|
+
if (options.fingerprint) {
|
|
20
|
+
session.metadata = { fingerprint: true };
|
|
21
|
+
}
|
|
22
|
+
return session;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/session/validate-session.ts
|
|
26
|
+
function validateSession(session, options = {}) {
|
|
27
|
+
const now = /* @__PURE__ */ new Date();
|
|
28
|
+
if (!session.id || !session.userId || !session.expiresAt) {
|
|
29
|
+
return { valid: false, reason: "invalid" };
|
|
30
|
+
}
|
|
31
|
+
if (now > session.expiresAt) {
|
|
32
|
+
return { valid: false, reason: "expired" };
|
|
33
|
+
}
|
|
34
|
+
if (options.idleTimeout && session.lastActivityAt) {
|
|
35
|
+
const idleTime = now.getTime() - session.lastActivityAt.getTime();
|
|
36
|
+
if (idleTime > options.idleTimeout) {
|
|
37
|
+
return { valid: false, reason: "idle-timeout" };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const totalLifetime = session.expiresAt.getTime() - session.createdAt.getTime();
|
|
41
|
+
const elapsed = now.getTime() - session.createdAt.getTime();
|
|
42
|
+
const shouldRefresh = elapsed > totalLifetime * 0.5;
|
|
43
|
+
return { valid: true, shouldRefresh };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/session/require-session.ts
|
|
47
|
+
function requireSession(getSession, options = {}) {
|
|
48
|
+
return function(handler) {
|
|
49
|
+
return async () => {
|
|
50
|
+
const session = await getSession();
|
|
51
|
+
if (!session) {
|
|
52
|
+
throw new SessionExpiredError("No active session found");
|
|
53
|
+
}
|
|
54
|
+
const validation = validateSession(session, options);
|
|
55
|
+
if (!validation.valid) {
|
|
56
|
+
throw new SessionExpiredError(
|
|
57
|
+
`Session ${validation.reason || "invalid"}`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return handler(session);
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { createSession, requireSession, validateSession };
|
|
66
|
+
//# sourceMappingURL=chunk-5MVLFEZI.js.map
|
|
67
|
+
//# sourceMappingURL=chunk-5MVLFEZI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/session/create-session.ts","../src/session/validate-session.ts","../src/session/require-session.ts"],"names":[],"mappings":"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","file":"chunk-5MVLFEZI.js","sourcesContent":["import type { Session, SessionOptions, User } from '../types';\nimport { randomBytes } from 'crypto';\n\n/**\n * Generates a secure random session ID\n */\nfunction generateSessionId(): string {\n const timestamp = Date.now().toString(36);\n const randomPart = randomBytes(16).toString('hex');\n return `session_${timestamp}_${randomPart}`;\n}\n\n/**\n * Creates a new session for a user\n *\n * @param userId - The user ID to create a session for\n * @param options - Session configuration options\n * @returns A new session object\n *\n * @example\n * ```ts\n * const session = createSession('user-123', {\n * expiresIn: 1000 * 60 * 60 * 24, // 24 hours\n * idleTimeout: 1000 * 60 * 30, // 30 minutes\n * });\n * ```\n */\nexport function createSession<TUser extends User = User>(\n userId: string,\n options: SessionOptions = {}\n): Session<TUser> {\n const now = new Date();\n const expiresIn = options.expiresIn ?? 1000 * 60 * 60 * 24 * 7; // 7 days default\n\n const session: Session<TUser> = {\n id: generateSessionId(),\n userId,\n expiresAt: new Date(now.getTime() + expiresIn),\n createdAt: now,\n lastActivityAt: now,\n };\n\n if (options.fingerprint) {\n session.metadata = { fingerprint: true };\n }\n\n return session;\n}\n","import type { Session, SessionOptions, User } from '../types';\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n valid: boolean;\n reason?: 'expired' | 'idle-timeout' | 'invalid';\n shouldRefresh?: boolean;\n}\n\n/**\n * Validates a session\n *\n * @param session - The session to validate\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```ts\n * const result = validateSession(session, {\n * idleTimeout: 1000 * 60 * 30, // 30 minutes\n * });\n *\n * if (!result.valid) {\n * throw new SessionExpiredError(result.reason);\n * }\n * ```\n */\nexport function validateSession<TUser extends User = User>(\n session: Session<TUser>,\n options: SessionOptions = {}\n): ValidationResult {\n const now = new Date();\n\n // Check if session structure is valid\n if (!session.id || !session.userId || !session.expiresAt) {\n return { valid: false, reason: 'invalid' };\n }\n\n // Check absolute expiration\n if (now > session.expiresAt) {\n return { valid: false, reason: 'expired' };\n }\n\n // Check idle timeout\n if (options.idleTimeout && session.lastActivityAt) {\n const idleTime = now.getTime() - session.lastActivityAt.getTime();\n if (idleTime > options.idleTimeout) {\n return { valid: false, reason: 'idle-timeout' };\n }\n }\n\n // Check if session should be refreshed (>50% through its lifetime)\n const totalLifetime =\n session.expiresAt.getTime() - session.createdAt.getTime();\n const elapsed = now.getTime() - session.createdAt.getTime();\n const shouldRefresh = elapsed > totalLifetime * 0.5;\n\n return { valid: true, shouldRefresh };\n}\n","import type { Session, SessionOptions, User } from '../types';\nimport { validateSession } from './validate-session';\nimport { SessionExpiredError } from '../errors';\n\n/**\n * Session handler callback\n */\nexport type SessionHandler<TUser extends User = User, TResult = unknown> = (\n _session: Session<TUser>\n) => TResult | Promise<TResult>;\n\n/**\n * Creates a guard that requires a valid session\n *\n * @param getSession - Function to retrieve the current session\n * @param options - Session options for validation\n * @returns A function that wraps a handler with session validation\n *\n * @example\n * ```ts\n * const guard = requireSession(\n * async () => getCurrentSession(),\n * { idleTimeout: 1000 * 60 * 30 }\n * );\n *\n * const handler = guard(async (session) => {\n * return { userId: session.userId };\n * });\n * ```\n */\nexport function requireSession<TUser extends User = User>(\n getSession: () => Session<TUser> | Promise<Session<TUser> | null> | null,\n options: SessionOptions = {}\n) {\n return function <TResult>(\n handler: SessionHandler<TUser, TResult>\n ): () => Promise<TResult> {\n return async () => {\n const session = await getSession();\n\n if (!session) {\n throw new SessionExpiredError('No active session found');\n }\n\n const validation = validateSession(session, options);\n\n if (!validation.valid) {\n throw new SessionExpiredError(\n `Session ${validation.reason || 'invalid'}`\n );\n }\n\n return handler(session);\n };\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-5XQQYIDO.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-LBCZ2NQO.cjs"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// src/errors/base-errors.ts
|
|
2
|
+
var AuthError = class _AuthError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(message, code) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "AuthError";
|
|
7
|
+
this.code = code;
|
|
8
|
+
Object.setPrototypeOf(this, _AuthError.prototype);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var AuthenticationError = class _AuthenticationError extends AuthError {
|
|
12
|
+
constructor(message = "Authentication failed") {
|
|
13
|
+
super(message, "AUTHENTICATION_ERROR");
|
|
14
|
+
this.name = "AuthenticationError";
|
|
15
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var AuthorizationError = class _AuthorizationError extends AuthError {
|
|
19
|
+
constructor(message = "Authorization failed") {
|
|
20
|
+
super(message, "AUTHORIZATION_ERROR");
|
|
21
|
+
this.name = "AuthorizationError";
|
|
22
|
+
Object.setPrototypeOf(this, _AuthorizationError.prototype);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var InvalidTokenError = class _InvalidTokenError extends AuthError {
|
|
26
|
+
constructor(message = "Invalid token") {
|
|
27
|
+
super(message, "INVALID_TOKEN");
|
|
28
|
+
this.name = "InvalidTokenError";
|
|
29
|
+
Object.setPrototypeOf(this, _InvalidTokenError.prototype);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var RateLimitError = class _RateLimitError extends AuthError {
|
|
33
|
+
constructor(message = "Rate limit exceeded") {
|
|
34
|
+
super(message, "RATE_LIMIT_EXCEEDED");
|
|
35
|
+
this.name = "RateLimitError";
|
|
36
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var CSRFError = class _CSRFError extends AuthError {
|
|
40
|
+
constructor(message = "CSRF validation failed") {
|
|
41
|
+
super(message, "CSRF_ERROR");
|
|
42
|
+
this.name = "CSRFError";
|
|
43
|
+
Object.setPrototypeOf(this, _CSRFError.prototype);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/errors/session-errors.ts
|
|
48
|
+
var SessionExpiredError = class _SessionExpiredError extends AuthError {
|
|
49
|
+
constructor(message = "Session expired") {
|
|
50
|
+
super(message, "SESSION_EXPIRED");
|
|
51
|
+
this.name = "SessionExpiredError";
|
|
52
|
+
Object.setPrototypeOf(this, _SessionExpiredError.prototype);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
var InvalidSessionError = class _InvalidSessionError extends AuthError {
|
|
56
|
+
constructor(message = "Invalid session") {
|
|
57
|
+
super(message, "INVALID_SESSION");
|
|
58
|
+
this.name = "InvalidSessionError";
|
|
59
|
+
Object.setPrototypeOf(this, _InvalidSessionError.prototype);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export { AuthError, AuthenticationError, AuthorizationError, CSRFError, InvalidSessionError, InvalidTokenError, RateLimitError, SessionExpiredError };
|
|
64
|
+
//# sourceMappingURL=chunk-MAVNKELK.js.map
|
|
65
|
+
//# sourceMappingURL=chunk-MAVNKELK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors/base-errors.ts","../src/errors/session-errors.ts"],"names":[],"mappings":";AAGO,IAAM,SAAA,GAAN,MAAM,UAAA,SAAkB,KAAA,CAAM;AAAA,EACnB,IAAA;AAAA,EAEhB,WAAA,CAAY,SAAiB,IAAA,EAAc;AACzC,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,UAAA,CAAU,SAAS,CAAA;AAAA,EACjD;AACF;AAKO,IAAM,mBAAA,GAAN,MAAM,oBAAA,SAA4B,SAAA,CAAU;AAAA,EACjD,WAAA,CAAY,UAAkB,uBAAA,EAAyB;AACrD,IAAA,KAAA,CAAM,SAAS,sBAAsB,CAAA;AACrC,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,oBAAA,CAAoB,SAAS,CAAA;AAAA,EAC3D;AACF;AAKO,IAAM,kBAAA,GAAN,MAAM,mBAAA,SAA2B,SAAA,CAAU;AAAA,EAChD,WAAA,CAAY,UAAkB,sBAAA,EAAwB;AACpD,IAAA,KAAA,CAAM,SAAS,qBAAqB,CAAA;AACpC,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,mBAAA,CAAmB,SAAS,CAAA;AAAA,EAC1D;AACF;AAKO,IAAM,iBAAA,GAAN,MAAM,kBAAA,SAA0B,SAAA,CAAU;AAAA,EAC/C,WAAA,CAAY,UAAkB,eAAA,EAAiB;AAC7C,IAAA,KAAA,CAAM,SAAS,eAAe,CAAA;AAC9B,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,kBAAA,CAAkB,SAAS,CAAA;AAAA,EACzD;AACF;AAKO,IAAM,cAAA,GAAN,MAAM,eAAA,SAAuB,SAAA,CAAU;AAAA,EAC5C,WAAA,CAAY,UAAkB,qBAAA,EAAuB;AACnD,IAAA,KAAA,CAAM,SAAS,qBAAqB,CAAA;AACpC,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,eAAA,CAAe,SAAS,CAAA;AAAA,EACtD;AACF;AAKO,IAAM,SAAA,GAAN,MAAM,UAAA,SAAkB,SAAA,CAAU;AAAA,EACvC,WAAA,CAAY,UAAkB,wBAAA,EAA0B;AACtD,IAAA,KAAA,CAAM,SAAS,YAAY,CAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,UAAA,CAAU,SAAS,CAAA;AAAA,EACjD;AACF;;;AC9DO,IAAM,mBAAA,GAAN,MAAM,oBAAA,SAA4B,SAAA,CAAU;AAAA,EACjD,WAAA,CAAY,UAAkB,iBAAA,EAAmB;AAC/C,IAAA,KAAA,CAAM,SAAS,iBAAiB,CAAA;AAChC,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,oBAAA,CAAoB,SAAS,CAAA;AAAA,EAC3D;AACF;AAKO,IAAM,mBAAA,GAAN,MAAM,oBAAA,SAA4B,SAAA,CAAU;AAAA,EACjD,WAAA,CAAY,UAAkB,iBAAA,EAAmB;AAC/C,IAAA,KAAA,CAAM,SAAS,iBAAiB,CAAA;AAChC,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,oBAAA,CAAoB,SAAS,CAAA;AAAA,EAC3D;AACF","file":"chunk-MAVNKELK.js","sourcesContent":["/**\n * Base authentication error\n */\nexport class AuthError extends Error {\n public readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = 'AuthError';\n this.code = code;\n Object.setPrototypeOf(this, AuthError.prototype);\n }\n}\n\n/**\n * Authentication failed error\n */\nexport class AuthenticationError extends AuthError {\n constructor(message: string = 'Authentication failed') {\n super(message, 'AUTHENTICATION_ERROR');\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Authorization failed error\n */\nexport class AuthorizationError extends AuthError {\n constructor(message: string = 'Authorization failed') {\n super(message, 'AUTHORIZATION_ERROR');\n this.name = 'AuthorizationError';\n Object.setPrototypeOf(this, AuthorizationError.prototype);\n }\n}\n\n/**\n * Invalid token error\n */\nexport class InvalidTokenError extends AuthError {\n constructor(message: string = 'Invalid token') {\n super(message, 'INVALID_TOKEN');\n this.name = 'InvalidTokenError';\n Object.setPrototypeOf(this, InvalidTokenError.prototype);\n }\n}\n\n/**\n * Rate limit exceeded error\n */\nexport class RateLimitError extends AuthError {\n constructor(message: string = 'Rate limit exceeded') {\n super(message, 'RATE_LIMIT_EXCEEDED');\n this.name = 'RateLimitError';\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\n/**\n * CSRF validation failed error\n */\nexport class CSRFError extends AuthError {\n constructor(message: string = 'CSRF validation failed') {\n super(message, 'CSRF_ERROR');\n this.name = 'CSRFError';\n Object.setPrototypeOf(this, CSRFError.prototype);\n }\n}\n","import { AuthError } from './base-errors';\n\n/**\n * Session expired error\n */\nexport class SessionExpiredError extends AuthError {\n constructor(message: string = 'Session expired') {\n super(message, 'SESSION_EXPIRED');\n this.name = 'SessionExpiredError';\n Object.setPrototypeOf(this, SessionExpiredError.prototype);\n }\n}\n\n/**\n * Invalid session error\n */\nexport class InvalidSessionError extends AuthError {\n constructor(message: string = 'Invalid session') {\n super(message, 'INVALID_SESSION');\n this.name = 'InvalidSessionError';\n Object.setPrototypeOf(this, InvalidSessionError.prototype);\n }\n}\n"]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkRGDYDO4P_cjs = require('./chunk-RGDYDO4P.cjs');
|
|
4
|
+
var crypto = require('crypto');
|
|
5
|
+
|
|
6
|
+
function generateSessionId() {
|
|
7
|
+
const timestamp = Date.now().toString(36);
|
|
8
|
+
const randomPart = crypto.randomBytes(16).toString("hex");
|
|
9
|
+
return `session_${timestamp}_${randomPart}`;
|
|
10
|
+
}
|
|
11
|
+
function createSession(userId, options = {}) {
|
|
12
|
+
const now = /* @__PURE__ */ new Date();
|
|
13
|
+
const expiresIn = options.expiresIn ?? 1e3 * 60 * 60 * 24 * 7;
|
|
14
|
+
const session = {
|
|
15
|
+
id: generateSessionId(),
|
|
16
|
+
userId,
|
|
17
|
+
expiresAt: new Date(now.getTime() + expiresIn),
|
|
18
|
+
createdAt: now,
|
|
19
|
+
lastActivityAt: now
|
|
20
|
+
};
|
|
21
|
+
if (options.fingerprint) {
|
|
22
|
+
session.metadata = { fingerprint: true };
|
|
23
|
+
}
|
|
24
|
+
return session;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// src/session/validate-session.ts
|
|
28
|
+
function validateSession(session, options = {}) {
|
|
29
|
+
const now = /* @__PURE__ */ new Date();
|
|
30
|
+
if (!session.id || !session.userId || !session.expiresAt) {
|
|
31
|
+
return { valid: false, reason: "invalid" };
|
|
32
|
+
}
|
|
33
|
+
if (now > session.expiresAt) {
|
|
34
|
+
return { valid: false, reason: "expired" };
|
|
35
|
+
}
|
|
36
|
+
if (options.idleTimeout && session.lastActivityAt) {
|
|
37
|
+
const idleTime = now.getTime() - session.lastActivityAt.getTime();
|
|
38
|
+
if (idleTime > options.idleTimeout) {
|
|
39
|
+
return { valid: false, reason: "idle-timeout" };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const totalLifetime = session.expiresAt.getTime() - session.createdAt.getTime();
|
|
43
|
+
const elapsed = now.getTime() - session.createdAt.getTime();
|
|
44
|
+
const shouldRefresh = elapsed > totalLifetime * 0.5;
|
|
45
|
+
return { valid: true, shouldRefresh };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/session/require-session.ts
|
|
49
|
+
function requireSession(getSession, options = {}) {
|
|
50
|
+
return function(handler) {
|
|
51
|
+
return async () => {
|
|
52
|
+
const session = await getSession();
|
|
53
|
+
if (!session) {
|
|
54
|
+
throw new chunkRGDYDO4P_cjs.SessionExpiredError("No active session found");
|
|
55
|
+
}
|
|
56
|
+
const validation = validateSession(session, options);
|
|
57
|
+
if (!validation.valid) {
|
|
58
|
+
throw new chunkRGDYDO4P_cjs.SessionExpiredError(
|
|
59
|
+
`Session ${validation.reason || "invalid"}`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return handler(session);
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
exports.createSession = createSession;
|
|
68
|
+
exports.requireSession = requireSession;
|
|
69
|
+
exports.validateSession = validateSession;
|
|
70
|
+
//# sourceMappingURL=chunk-NW5NFB77.cjs.map
|
|
71
|
+
//# sourceMappingURL=chunk-NW5NFB77.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/session/create-session.ts","../src/session/validate-session.ts","../src/session/require-session.ts"],"names":["randomBytes","SessionExpiredError"],"mappings":"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","file":"chunk-NW5NFB77.cjs","sourcesContent":["import type { Session, SessionOptions, User } from '../types';\nimport { randomBytes } from 'crypto';\n\n/**\n * Generates a secure random session ID\n */\nfunction generateSessionId(): string {\n const timestamp = Date.now().toString(36);\n const randomPart = randomBytes(16).toString('hex');\n return `session_${timestamp}_${randomPart}`;\n}\n\n/**\n * Creates a new session for a user\n *\n * @param userId - The user ID to create a session for\n * @param options - Session configuration options\n * @returns A new session object\n *\n * @example\n * ```ts\n * const session = createSession('user-123', {\n * expiresIn: 1000 * 60 * 60 * 24, // 24 hours\n * idleTimeout: 1000 * 60 * 30, // 30 minutes\n * });\n * ```\n */\nexport function createSession<TUser extends User = User>(\n userId: string,\n options: SessionOptions = {}\n): Session<TUser> {\n const now = new Date();\n const expiresIn = options.expiresIn ?? 1000 * 60 * 60 * 24 * 7; // 7 days default\n\n const session: Session<TUser> = {\n id: generateSessionId(),\n userId,\n expiresAt: new Date(now.getTime() + expiresIn),\n createdAt: now,\n lastActivityAt: now,\n };\n\n if (options.fingerprint) {\n session.metadata = { fingerprint: true };\n }\n\n return session;\n}\n","import type { Session, SessionOptions, User } from '../types';\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n valid: boolean;\n reason?: 'expired' | 'idle-timeout' | 'invalid';\n shouldRefresh?: boolean;\n}\n\n/**\n * Validates a session\n *\n * @param session - The session to validate\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```ts\n * const result = validateSession(session, {\n * idleTimeout: 1000 * 60 * 30, // 30 minutes\n * });\n *\n * if (!result.valid) {\n * throw new SessionExpiredError(result.reason);\n * }\n * ```\n */\nexport function validateSession<TUser extends User = User>(\n session: Session<TUser>,\n options: SessionOptions = {}\n): ValidationResult {\n const now = new Date();\n\n // Check if session structure is valid\n if (!session.id || !session.userId || !session.expiresAt) {\n return { valid: false, reason: 'invalid' };\n }\n\n // Check absolute expiration\n if (now > session.expiresAt) {\n return { valid: false, reason: 'expired' };\n }\n\n // Check idle timeout\n if (options.idleTimeout && session.lastActivityAt) {\n const idleTime = now.getTime() - session.lastActivityAt.getTime();\n if (idleTime > options.idleTimeout) {\n return { valid: false, reason: 'idle-timeout' };\n }\n }\n\n // Check if session should be refreshed (>50% through its lifetime)\n const totalLifetime =\n session.expiresAt.getTime() - session.createdAt.getTime();\n const elapsed = now.getTime() - session.createdAt.getTime();\n const shouldRefresh = elapsed > totalLifetime * 0.5;\n\n return { valid: true, shouldRefresh };\n}\n","import type { Session, SessionOptions, User } from '../types';\nimport { validateSession } from './validate-session';\nimport { SessionExpiredError } from '../errors';\n\n/**\n * Session handler callback\n */\nexport type SessionHandler<TUser extends User = User, TResult = unknown> = (\n _session: Session<TUser>\n) => TResult | Promise<TResult>;\n\n/**\n * Creates a guard that requires a valid session\n *\n * @param getSession - Function to retrieve the current session\n * @param options - Session options for validation\n * @returns A function that wraps a handler with session validation\n *\n * @example\n * ```ts\n * const guard = requireSession(\n * async () => getCurrentSession(),\n * { idleTimeout: 1000 * 60 * 30 }\n * );\n *\n * const handler = guard(async (session) => {\n * return { userId: session.userId };\n * });\n * ```\n */\nexport function requireSession<TUser extends User = User>(\n getSession: () => Session<TUser> | Promise<Session<TUser> | null> | null,\n options: SessionOptions = {}\n) {\n return function <TResult>(\n handler: SessionHandler<TUser, TResult>\n ): () => Promise<TResult> {\n return async () => {\n const session = await getSession();\n\n if (!session) {\n throw new SessionExpiredError('No active session found');\n }\n\n const validation = validateSession(session, options);\n\n if (!validation.valid) {\n throw new SessionExpiredError(\n `Session ${validation.reason || 'invalid'}`\n );\n }\n\n return handler(session);\n };\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-OIQMYYPZ.cjs"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/errors/base-errors.ts
|
|
4
|
+
var AuthError = class _AuthError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(message, code) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "AuthError";
|
|
9
|
+
this.code = code;
|
|
10
|
+
Object.setPrototypeOf(this, _AuthError.prototype);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
var AuthenticationError = class _AuthenticationError extends AuthError {
|
|
14
|
+
constructor(message = "Authentication failed") {
|
|
15
|
+
super(message, "AUTHENTICATION_ERROR");
|
|
16
|
+
this.name = "AuthenticationError";
|
|
17
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var AuthorizationError = class _AuthorizationError extends AuthError {
|
|
21
|
+
constructor(message = "Authorization failed") {
|
|
22
|
+
super(message, "AUTHORIZATION_ERROR");
|
|
23
|
+
this.name = "AuthorizationError";
|
|
24
|
+
Object.setPrototypeOf(this, _AuthorizationError.prototype);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var InvalidTokenError = class _InvalidTokenError extends AuthError {
|
|
28
|
+
constructor(message = "Invalid token") {
|
|
29
|
+
super(message, "INVALID_TOKEN");
|
|
30
|
+
this.name = "InvalidTokenError";
|
|
31
|
+
Object.setPrototypeOf(this, _InvalidTokenError.prototype);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var RateLimitError = class _RateLimitError extends AuthError {
|
|
35
|
+
constructor(message = "Rate limit exceeded") {
|
|
36
|
+
super(message, "RATE_LIMIT_EXCEEDED");
|
|
37
|
+
this.name = "RateLimitError";
|
|
38
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var CSRFError = class _CSRFError extends AuthError {
|
|
42
|
+
constructor(message = "CSRF validation failed") {
|
|
43
|
+
super(message, "CSRF_ERROR");
|
|
44
|
+
this.name = "CSRFError";
|
|
45
|
+
Object.setPrototypeOf(this, _CSRFError.prototype);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// src/errors/session-errors.ts
|
|
50
|
+
var SessionExpiredError = class _SessionExpiredError extends AuthError {
|
|
51
|
+
constructor(message = "Session expired") {
|
|
52
|
+
super(message, "SESSION_EXPIRED");
|
|
53
|
+
this.name = "SessionExpiredError";
|
|
54
|
+
Object.setPrototypeOf(this, _SessionExpiredError.prototype);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
var InvalidSessionError = class _InvalidSessionError extends AuthError {
|
|
58
|
+
constructor(message = "Invalid session") {
|
|
59
|
+
super(message, "INVALID_SESSION");
|
|
60
|
+
this.name = "InvalidSessionError";
|
|
61
|
+
Object.setPrototypeOf(this, _InvalidSessionError.prototype);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
exports.AuthError = AuthError;
|
|
66
|
+
exports.AuthenticationError = AuthenticationError;
|
|
67
|
+
exports.AuthorizationError = AuthorizationError;
|
|
68
|
+
exports.CSRFError = CSRFError;
|
|
69
|
+
exports.InvalidSessionError = InvalidSessionError;
|
|
70
|
+
exports.InvalidTokenError = InvalidTokenError;
|
|
71
|
+
exports.RateLimitError = RateLimitError;
|
|
72
|
+
exports.SessionExpiredError = SessionExpiredError;
|
|
73
|
+
//# sourceMappingURL=chunk-RGDYDO4P.cjs.map
|
|
74
|
+
//# sourceMappingURL=chunk-RGDYDO4P.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors/base-errors.ts","../src/errors/session-errors.ts"],"names":[],"mappings":";;;AAGO,IAAM,SAAA,GAAN,MAAM,UAAA,SAAkB,KAAA,CAAM;AAAA,EACnB,IAAA;AAAA,EAEhB,WAAA,CAAY,SAAiB,IAAA,EAAc;AACzC,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,UAAA,CAAU,SAAS,CAAA;AAAA,EACjD;AACF;AAKO,IAAM,mBAAA,GAAN,MAAM,oBAAA,SAA4B,SAAA,CAAU;AAAA,EACjD,WAAA,CAAY,UAAkB,uBAAA,EAAyB;AACrD,IAAA,KAAA,CAAM,SAAS,sBAAsB,CAAA;AACrC,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,oBAAA,CAAoB,SAAS,CAAA;AAAA,EAC3D;AACF;AAKO,IAAM,kBAAA,GAAN,MAAM,mBAAA,SAA2B,SAAA,CAAU;AAAA,EAChD,WAAA,CAAY,UAAkB,sBAAA,EAAwB;AACpD,IAAA,KAAA,CAAM,SAAS,qBAAqB,CAAA;AACpC,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,mBAAA,CAAmB,SAAS,CAAA;AAAA,EAC1D;AACF;AAKO,IAAM,iBAAA,GAAN,MAAM,kBAAA,SAA0B,SAAA,CAAU;AAAA,EAC/C,WAAA,CAAY,UAAkB,eAAA,EAAiB;AAC7C,IAAA,KAAA,CAAM,SAAS,eAAe,CAAA;AAC9B,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,kBAAA,CAAkB,SAAS,CAAA;AAAA,EACzD;AACF;AAKO,IAAM,cAAA,GAAN,MAAM,eAAA,SAAuB,SAAA,CAAU;AAAA,EAC5C,WAAA,CAAY,UAAkB,qBAAA,EAAuB;AACnD,IAAA,KAAA,CAAM,SAAS,qBAAqB,CAAA;AACpC,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,eAAA,CAAe,SAAS,CAAA;AAAA,EACtD;AACF;AAKO,IAAM,SAAA,GAAN,MAAM,UAAA,SAAkB,SAAA,CAAU;AAAA,EACvC,WAAA,CAAY,UAAkB,wBAAA,EAA0B;AACtD,IAAA,KAAA,CAAM,SAAS,YAAY,CAAA;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,UAAA,CAAU,SAAS,CAAA;AAAA,EACjD;AACF;;;AC9DO,IAAM,mBAAA,GAAN,MAAM,oBAAA,SAA4B,SAAA,CAAU;AAAA,EACjD,WAAA,CAAY,UAAkB,iBAAA,EAAmB;AAC/C,IAAA,KAAA,CAAM,SAAS,iBAAiB,CAAA;AAChC,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,oBAAA,CAAoB,SAAS,CAAA;AAAA,EAC3D;AACF;AAKO,IAAM,mBAAA,GAAN,MAAM,oBAAA,SAA4B,SAAA,CAAU;AAAA,EACjD,WAAA,CAAY,UAAkB,iBAAA,EAAmB;AAC/C,IAAA,KAAA,CAAM,SAAS,iBAAiB,CAAA;AAChC,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,oBAAA,CAAoB,SAAS,CAAA;AAAA,EAC3D;AACF","file":"chunk-RGDYDO4P.cjs","sourcesContent":["/**\n * Base authentication error\n */\nexport class AuthError extends Error {\n public readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = 'AuthError';\n this.code = code;\n Object.setPrototypeOf(this, AuthError.prototype);\n }\n}\n\n/**\n * Authentication failed error\n */\nexport class AuthenticationError extends AuthError {\n constructor(message: string = 'Authentication failed') {\n super(message, 'AUTHENTICATION_ERROR');\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Authorization failed error\n */\nexport class AuthorizationError extends AuthError {\n constructor(message: string = 'Authorization failed') {\n super(message, 'AUTHORIZATION_ERROR');\n this.name = 'AuthorizationError';\n Object.setPrototypeOf(this, AuthorizationError.prototype);\n }\n}\n\n/**\n * Invalid token error\n */\nexport class InvalidTokenError extends AuthError {\n constructor(message: string = 'Invalid token') {\n super(message, 'INVALID_TOKEN');\n this.name = 'InvalidTokenError';\n Object.setPrototypeOf(this, InvalidTokenError.prototype);\n }\n}\n\n/**\n * Rate limit exceeded error\n */\nexport class RateLimitError extends AuthError {\n constructor(message: string = 'Rate limit exceeded') {\n super(message, 'RATE_LIMIT_EXCEEDED');\n this.name = 'RateLimitError';\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\n/**\n * CSRF validation failed error\n */\nexport class CSRFError extends AuthError {\n constructor(message: string = 'CSRF validation failed') {\n super(message, 'CSRF_ERROR');\n this.name = 'CSRFError';\n Object.setPrototypeOf(this, CSRFError.prototype);\n }\n}\n","import { AuthError } from './base-errors';\n\n/**\n * Session expired error\n */\nexport class SessionExpiredError extends AuthError {\n constructor(message: string = 'Session expired') {\n super(message, 'SESSION_EXPIRED');\n this.name = 'SessionExpiredError';\n Object.setPrototypeOf(this, SessionExpiredError.prototype);\n }\n}\n\n/**\n * Invalid session error\n */\nexport class InvalidSessionError extends AuthError {\n constructor(message: string = 'Invalid session') {\n super(message, 'INVALID_SESSION');\n this.name = 'InvalidSessionError';\n Object.setPrototypeOf(this, InvalidSessionError.prototype);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-USPZICST.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkRGDYDO4P_cjs = require('../chunk-RGDYDO4P.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "AuthError", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunkRGDYDO4P_cjs.AuthError; }
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(exports, "AuthenticationError", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () { return chunkRGDYDO4P_cjs.AuthenticationError; }
|
|
14
|
+
});
|
|
15
|
+
Object.defineProperty(exports, "AuthorizationError", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return chunkRGDYDO4P_cjs.AuthorizationError; }
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "CSRFError", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return chunkRGDYDO4P_cjs.CSRFError; }
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports, "InvalidSessionError", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return chunkRGDYDO4P_cjs.InvalidSessionError; }
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(exports, "InvalidTokenError", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () { return chunkRGDYDO4P_cjs.InvalidTokenError; }
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "RateLimitError", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () { return chunkRGDYDO4P_cjs.RateLimitError; }
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(exports, "SessionExpiredError", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
get: function () { return chunkRGDYDO4P_cjs.SessionExpiredError; }
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=index.cjs.map
|
|
40
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base authentication error
|
|
3
|
+
*/
|
|
4
|
+
declare class AuthError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
constructor(message: string, code: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Authentication failed error
|
|
10
|
+
*/
|
|
11
|
+
declare class AuthenticationError extends AuthError {
|
|
12
|
+
constructor(message?: string);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Authorization failed error
|
|
16
|
+
*/
|
|
17
|
+
declare class AuthorizationError extends AuthError {
|
|
18
|
+
constructor(message?: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Invalid token error
|
|
22
|
+
*/
|
|
23
|
+
declare class InvalidTokenError extends AuthError {
|
|
24
|
+
constructor(message?: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Rate limit exceeded error
|
|
28
|
+
*/
|
|
29
|
+
declare class RateLimitError extends AuthError {
|
|
30
|
+
constructor(message?: string);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* CSRF validation failed error
|
|
34
|
+
*/
|
|
35
|
+
declare class CSRFError extends AuthError {
|
|
36
|
+
constructor(message?: string);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Session expired error
|
|
41
|
+
*/
|
|
42
|
+
declare class SessionExpiredError extends AuthError {
|
|
43
|
+
constructor(message?: string);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Invalid session error
|
|
47
|
+
*/
|
|
48
|
+
declare class InvalidSessionError extends AuthError {
|
|
49
|
+
constructor(message?: string);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { AuthError, AuthenticationError, AuthorizationError, CSRFError, InvalidSessionError, InvalidTokenError, RateLimitError, SessionExpiredError };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base authentication error
|
|
3
|
+
*/
|
|
4
|
+
declare class AuthError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
constructor(message: string, code: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Authentication failed error
|
|
10
|
+
*/
|
|
11
|
+
declare class AuthenticationError extends AuthError {
|
|
12
|
+
constructor(message?: string);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Authorization failed error
|
|
16
|
+
*/
|
|
17
|
+
declare class AuthorizationError extends AuthError {
|
|
18
|
+
constructor(message?: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Invalid token error
|
|
22
|
+
*/
|
|
23
|
+
declare class InvalidTokenError extends AuthError {
|
|
24
|
+
constructor(message?: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Rate limit exceeded error
|
|
28
|
+
*/
|
|
29
|
+
declare class RateLimitError extends AuthError {
|
|
30
|
+
constructor(message?: string);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* CSRF validation failed error
|
|
34
|
+
*/
|
|
35
|
+
declare class CSRFError extends AuthError {
|
|
36
|
+
constructor(message?: string);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Session expired error
|
|
41
|
+
*/
|
|
42
|
+
declare class SessionExpiredError extends AuthError {
|
|
43
|
+
constructor(message?: string);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Invalid session error
|
|
47
|
+
*/
|
|
48
|
+
declare class InvalidSessionError extends AuthError {
|
|
49
|
+
constructor(message?: string);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { AuthError, AuthenticationError, AuthorizationError, CSRFError, InvalidSessionError, InvalidTokenError, RateLimitError, SessionExpiredError };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for @amtarc/auth-utils
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Base user type - meant to be extended by consumers
|
|
6
|
+
*/
|
|
7
|
+
interface User {
|
|
8
|
+
id: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Session data structure
|
|
13
|
+
*/
|
|
14
|
+
interface Session<TUser extends User = User> {
|
|
15
|
+
id: string;
|
|
16
|
+
userId: string;
|
|
17
|
+
user?: TUser;
|
|
18
|
+
expiresAt: Date;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
lastActivityAt: Date;
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Session options
|
|
25
|
+
*/
|
|
26
|
+
interface SessionOptions {
|
|
27
|
+
/** Session expiration time in milliseconds */
|
|
28
|
+
expiresIn?: number;
|
|
29
|
+
/** Idle timeout in milliseconds */
|
|
30
|
+
idleTimeout?: number;
|
|
31
|
+
/** Absolute timeout in milliseconds */
|
|
32
|
+
absoluteTimeout?: number;
|
|
33
|
+
/** Enable session fingerprinting */
|
|
34
|
+
fingerprint?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Cookie options
|
|
38
|
+
*/
|
|
39
|
+
interface CookieOptions {
|
|
40
|
+
httpOnly?: boolean;
|
|
41
|
+
secure?: boolean;
|
|
42
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
43
|
+
domain?: string;
|
|
44
|
+
path?: string;
|
|
45
|
+
maxAge?: number;
|
|
46
|
+
signed?: boolean;
|
|
47
|
+
encrypted?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Request context (framework-agnostic)
|
|
51
|
+
*/
|
|
52
|
+
interface RequestContext {
|
|
53
|
+
headers: Record<string, string | string[] | undefined>;
|
|
54
|
+
cookies: Record<string, string>;
|
|
55
|
+
url: string;
|
|
56
|
+
method: string;
|
|
57
|
+
ip?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Response context (framework-agnostic)
|
|
61
|
+
*/
|
|
62
|
+
interface ResponseContext {
|
|
63
|
+
setHeader(_name: string, _value: string): void;
|
|
64
|
+
setCookie(_name: string, _value: string, _options?: CookieOptions): void;
|
|
65
|
+
redirect?(_url: string, _status?: number): void;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates a new session for a user
|
|
70
|
+
*
|
|
71
|
+
* @param userId - The user ID to create a session for
|
|
72
|
+
* @param options - Session configuration options
|
|
73
|
+
* @returns A new session object
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const session = createSession('user-123', {
|
|
78
|
+
* expiresIn: 1000 * 60 * 60 * 24, // 24 hours
|
|
79
|
+
* idleTimeout: 1000 * 60 * 30, // 30 minutes
|
|
80
|
+
* });
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
declare function createSession<TUser extends User = User>(userId: string, options?: SessionOptions): Session<TUser>;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Validation result
|
|
87
|
+
*/
|
|
88
|
+
interface ValidationResult {
|
|
89
|
+
valid: boolean;
|
|
90
|
+
reason?: 'expired' | 'idle-timeout' | 'invalid';
|
|
91
|
+
shouldRefresh?: boolean;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Validates a session
|
|
95
|
+
*
|
|
96
|
+
* @param session - The session to validate
|
|
97
|
+
* @param options - Validation options
|
|
98
|
+
* @returns Validation result
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* const result = validateSession(session, {
|
|
103
|
+
* idleTimeout: 1000 * 60 * 30, // 30 minutes
|
|
104
|
+
* });
|
|
105
|
+
*
|
|
106
|
+
* if (!result.valid) {
|
|
107
|
+
* throw new SessionExpiredError(result.reason);
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
declare function validateSession<TUser extends User = User>(session: Session<TUser>, options?: SessionOptions): ValidationResult;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Session handler callback
|
|
115
|
+
*/
|
|
116
|
+
type SessionHandler<TUser extends User = User, TResult = unknown> = (_session: Session<TUser>) => TResult | Promise<TResult>;
|
|
117
|
+
/**
|
|
118
|
+
* Creates a guard that requires a valid session
|
|
119
|
+
*
|
|
120
|
+
* @param getSession - Function to retrieve the current session
|
|
121
|
+
* @param options - Session options for validation
|
|
122
|
+
* @returns A function that wraps a handler with session validation
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* const guard = requireSession(
|
|
127
|
+
* async () => getCurrentSession(),
|
|
128
|
+
* { idleTimeout: 1000 * 60 * 30 }
|
|
129
|
+
* );
|
|
130
|
+
*
|
|
131
|
+
* const handler = guard(async (session) => {
|
|
132
|
+
* return { userId: session.userId };
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
declare function requireSession<TUser extends User = User>(getSession: () => Session<TUser> | Promise<Session<TUser> | null> | null, options?: SessionOptions): <TResult>(handler: SessionHandler<TUser, TResult>) => () => Promise<TResult>;
|
|
137
|
+
|
|
138
|
+
export { type CookieOptions as C, type RequestContext as R, type Session as S, type User as U, type ResponseContext as a, type SessionOptions as b, createSession as c, requireSession as r, validateSession as v };
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for @amtarc/auth-utils
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Base user type - meant to be extended by consumers
|
|
6
|
+
*/
|
|
7
|
+
interface User {
|
|
8
|
+
id: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Session data structure
|
|
13
|
+
*/
|
|
14
|
+
interface Session<TUser extends User = User> {
|
|
15
|
+
id: string;
|
|
16
|
+
userId: string;
|
|
17
|
+
user?: TUser;
|
|
18
|
+
expiresAt: Date;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
lastActivityAt: Date;
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Session options
|
|
25
|
+
*/
|
|
26
|
+
interface SessionOptions {
|
|
27
|
+
/** Session expiration time in milliseconds */
|
|
28
|
+
expiresIn?: number;
|
|
29
|
+
/** Idle timeout in milliseconds */
|
|
30
|
+
idleTimeout?: number;
|
|
31
|
+
/** Absolute timeout in milliseconds */
|
|
32
|
+
absoluteTimeout?: number;
|
|
33
|
+
/** Enable session fingerprinting */
|
|
34
|
+
fingerprint?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Cookie options
|
|
38
|
+
*/
|
|
39
|
+
interface CookieOptions {
|
|
40
|
+
httpOnly?: boolean;
|
|
41
|
+
secure?: boolean;
|
|
42
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
43
|
+
domain?: string;
|
|
44
|
+
path?: string;
|
|
45
|
+
maxAge?: number;
|
|
46
|
+
signed?: boolean;
|
|
47
|
+
encrypted?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Request context (framework-agnostic)
|
|
51
|
+
*/
|
|
52
|
+
interface RequestContext {
|
|
53
|
+
headers: Record<string, string | string[] | undefined>;
|
|
54
|
+
cookies: Record<string, string>;
|
|
55
|
+
url: string;
|
|
56
|
+
method: string;
|
|
57
|
+
ip?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Response context (framework-agnostic)
|
|
61
|
+
*/
|
|
62
|
+
interface ResponseContext {
|
|
63
|
+
setHeader(_name: string, _value: string): void;
|
|
64
|
+
setCookie(_name: string, _value: string, _options?: CookieOptions): void;
|
|
65
|
+
redirect?(_url: string, _status?: number): void;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates a new session for a user
|
|
70
|
+
*
|
|
71
|
+
* @param userId - The user ID to create a session for
|
|
72
|
+
* @param options - Session configuration options
|
|
73
|
+
* @returns A new session object
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const session = createSession('user-123', {
|
|
78
|
+
* expiresIn: 1000 * 60 * 60 * 24, // 24 hours
|
|
79
|
+
* idleTimeout: 1000 * 60 * 30, // 30 minutes
|
|
80
|
+
* });
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
declare function createSession<TUser extends User = User>(userId: string, options?: SessionOptions): Session<TUser>;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Validation result
|
|
87
|
+
*/
|
|
88
|
+
interface ValidationResult {
|
|
89
|
+
valid: boolean;
|
|
90
|
+
reason?: 'expired' | 'idle-timeout' | 'invalid';
|
|
91
|
+
shouldRefresh?: boolean;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Validates a session
|
|
95
|
+
*
|
|
96
|
+
* @param session - The session to validate
|
|
97
|
+
* @param options - Validation options
|
|
98
|
+
* @returns Validation result
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* const result = validateSession(session, {
|
|
103
|
+
* idleTimeout: 1000 * 60 * 30, // 30 minutes
|
|
104
|
+
* });
|
|
105
|
+
*
|
|
106
|
+
* if (!result.valid) {
|
|
107
|
+
* throw new SessionExpiredError(result.reason);
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
declare function validateSession<TUser extends User = User>(session: Session<TUser>, options?: SessionOptions): ValidationResult;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Session handler callback
|
|
115
|
+
*/
|
|
116
|
+
type SessionHandler<TUser extends User = User, TResult = unknown> = (_session: Session<TUser>) => TResult | Promise<TResult>;
|
|
117
|
+
/**
|
|
118
|
+
* Creates a guard that requires a valid session
|
|
119
|
+
*
|
|
120
|
+
* @param getSession - Function to retrieve the current session
|
|
121
|
+
* @param options - Session options for validation
|
|
122
|
+
* @returns A function that wraps a handler with session validation
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* const guard = requireSession(
|
|
127
|
+
* async () => getCurrentSession(),
|
|
128
|
+
* { idleTimeout: 1000 * 60 * 30 }
|
|
129
|
+
* );
|
|
130
|
+
*
|
|
131
|
+
* const handler = guard(async (session) => {
|
|
132
|
+
* return { userId: session.userId };
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
declare function requireSession<TUser extends User = User>(getSession: () => Session<TUser> | Promise<Session<TUser> | null> | null, options?: SessionOptions): <TResult>(handler: SessionHandler<TUser, TResult>) => () => Promise<TResult>;
|
|
137
|
+
|
|
138
|
+
export { type CookieOptions as C, type RequestContext as R, type Session as S, type User as U, type ResponseContext as a, type SessionOptions as b, createSession as c, requireSession as r, validateSession as v };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('./chunk-OIQMYYPZ.cjs');
|
|
4
|
+
require('./chunk-LBCZ2NQO.cjs');
|
|
5
|
+
var chunkNW5NFB77_cjs = require('./chunk-NW5NFB77.cjs');
|
|
6
|
+
var chunkRGDYDO4P_cjs = require('./chunk-RGDYDO4P.cjs');
|
|
7
|
+
|
|
8
|
+
// src/index.ts
|
|
9
|
+
var VERSION = "1.0.0";
|
|
10
|
+
|
|
11
|
+
Object.defineProperty(exports, "createSession", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () { return chunkNW5NFB77_cjs.createSession; }
|
|
14
|
+
});
|
|
15
|
+
Object.defineProperty(exports, "requireSession", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return chunkNW5NFB77_cjs.requireSession; }
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "validateSession", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return chunkNW5NFB77_cjs.validateSession; }
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports, "AuthError", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return chunkRGDYDO4P_cjs.AuthError; }
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(exports, "AuthenticationError", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () { return chunkRGDYDO4P_cjs.AuthenticationError; }
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "AuthorizationError", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () { return chunkRGDYDO4P_cjs.AuthorizationError; }
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(exports, "CSRFError", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
get: function () { return chunkRGDYDO4P_cjs.CSRFError; }
|
|
38
|
+
});
|
|
39
|
+
Object.defineProperty(exports, "InvalidSessionError", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
get: function () { return chunkRGDYDO4P_cjs.InvalidSessionError; }
|
|
42
|
+
});
|
|
43
|
+
Object.defineProperty(exports, "InvalidTokenError", {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: function () { return chunkRGDYDO4P_cjs.InvalidTokenError; }
|
|
46
|
+
});
|
|
47
|
+
Object.defineProperty(exports, "RateLimitError", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
get: function () { return chunkRGDYDO4P_cjs.RateLimitError; }
|
|
50
|
+
});
|
|
51
|
+
Object.defineProperty(exports, "SessionExpiredError", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
get: function () { return chunkRGDYDO4P_cjs.SessionExpiredError; }
|
|
54
|
+
});
|
|
55
|
+
exports.VERSION = VERSION;
|
|
56
|
+
//# sourceMappingURL=index.cjs.map
|
|
57
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;AAYO,IAAM,OAAA,GAAU","file":"index.cjs","sourcesContent":["/**\n * @amtarc/auth-utils\n *\n * Enterprise-grade authentication and session management utilities\n */\n\nexport * from './types';\nexport * from './session';\nexport * from './guards';\nexport * from './cookies';\nexport * from './errors';\n\nexport const VERSION = '1.0.0';\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { C as CookieOptions, R as RequestContext, a as ResponseContext, S as Session, b as SessionOptions, U as User, c as createSession, r as requireSession, v as validateSession } from './index-Bg3pYjD_.cjs';
|
|
2
|
+
export { AuthError, AuthenticationError, AuthorizationError, CSRFError, InvalidSessionError, InvalidTokenError, RateLimitError, SessionExpiredError } from './errors/index.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @amtarc/auth-utils
|
|
6
|
+
*
|
|
7
|
+
* Enterprise-grade authentication and session management utilities
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
declare const VERSION = "1.0.0";
|
|
11
|
+
|
|
12
|
+
export { VERSION };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { C as CookieOptions, R as RequestContext, a as ResponseContext, S as Session, b as SessionOptions, U as User, c as createSession, r as requireSession, v as validateSession } from './index-Bg3pYjD_.js';
|
|
2
|
+
export { AuthError, AuthenticationError, AuthorizationError, CSRFError, InvalidSessionError, InvalidTokenError, RateLimitError, SessionExpiredError } from './errors/index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @amtarc/auth-utils
|
|
6
|
+
*
|
|
7
|
+
* Enterprise-grade authentication and session management utilities
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
declare const VERSION = "1.0.0";
|
|
11
|
+
|
|
12
|
+
export { VERSION };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import './chunk-USPZICST.js';
|
|
2
|
+
import './chunk-5XQQYIDO.js';
|
|
3
|
+
export { createSession, requireSession, validateSession } from './chunk-5MVLFEZI.js';
|
|
4
|
+
export { AuthError, AuthenticationError, AuthorizationError, CSRFError, InvalidSessionError, InvalidTokenError, RateLimitError, SessionExpiredError } from './chunk-MAVNKELK.js';
|
|
5
|
+
|
|
6
|
+
// src/index.ts
|
|
7
|
+
var VERSION = "1.0.0";
|
|
8
|
+
|
|
9
|
+
export { VERSION };
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAYO,IAAM,OAAA,GAAU","file":"index.js","sourcesContent":["/**\n * @amtarc/auth-utils\n *\n * Enterprise-grade authentication and session management utilities\n */\n\nexport * from './types';\nexport * from './session';\nexport * from './guards';\nexport * from './cookies';\nexport * from './errors';\n\nexport const VERSION = '1.0.0';\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkNW5NFB77_cjs = require('../chunk-NW5NFB77.cjs');
|
|
4
|
+
require('../chunk-RGDYDO4P.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "createSession", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkNW5NFB77_cjs.createSession; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "requireSession", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkNW5NFB77_cjs.requireSession; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "validateSession", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunkNW5NFB77_cjs.validateSession; }
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=index.cjs.map
|
|
21
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { S as Session, b as SessionOptions, c as createSession, r as requireSession, v as validateSession } from '../index-Bg3pYjD_.cjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { S as Session, b as SessionOptions, c as createSession, r as requireSession, v as validateSession } from '../index-Bg3pYjD_.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@amtarc/auth-utils",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Core authentication and session management utilities",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"require": "./dist/index.cjs",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./session": {
|
|
13
|
+
"import": "./dist/session/index.js",
|
|
14
|
+
"require": "./dist/session/index.cjs",
|
|
15
|
+
"types": "./dist/session/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./guards": {
|
|
18
|
+
"import": "./dist/guards/index.js",
|
|
19
|
+
"require": "./dist/guards/index.cjs",
|
|
20
|
+
"types": "./dist/guards/index.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./cookies": {
|
|
23
|
+
"import": "./dist/cookies/index.js",
|
|
24
|
+
"require": "./dist/cookies/index.cjs",
|
|
25
|
+
"types": "./dist/cookies/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"./errors": {
|
|
28
|
+
"import": "./dist/errors/index.js",
|
|
29
|
+
"require": "./dist/errors/index.cjs",
|
|
30
|
+
"types": "./dist/errors/index.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"keywords": [
|
|
39
|
+
"authentication",
|
|
40
|
+
"session",
|
|
41
|
+
"security",
|
|
42
|
+
"typescript",
|
|
43
|
+
"guards"
|
|
44
|
+
],
|
|
45
|
+
"author": "amtarc",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^20.11.17",
|
|
52
|
+
"@vitest/coverage-v8": "^1.3.1",
|
|
53
|
+
"tsup": "^8.0.2",
|
|
54
|
+
"typescript": "^5.3.3",
|
|
55
|
+
"vitest": "^1.3.1"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"typescript": ">=5.0.0"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsup",
|
|
62
|
+
"dev": "tsup --watch",
|
|
63
|
+
"lint": "eslint src/",
|
|
64
|
+
"lint:fix": "eslint src/ --fix",
|
|
65
|
+
"test": "vitest",
|
|
66
|
+
"test:run": "vitest run",
|
|
67
|
+
"test:coverage": "vitest run --coverage",
|
|
68
|
+
"typecheck": "tsc --noEmit",
|
|
69
|
+
"clean": "rm -rf dist"
|
|
70
|
+
}
|
|
71
|
+
}
|