@veloxts/auth 0.6.91 → 0.6.93
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/CHANGELOG.md +18 -0
- package/GUIDE.md +39 -0
- package/dist/guards-narrowing.d.ts +56 -1
- package/dist/guards-narrowing.js +33 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @veloxts/auth
|
|
2
2
|
|
|
3
|
+
## 0.6.93
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feat(router): add Resource API with phantom types for context-dependent outputs
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @veloxts/core@0.6.93
|
|
10
|
+
- @veloxts/router@0.6.93
|
|
11
|
+
|
|
12
|
+
## 0.6.92
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- feat(storage): add provider factories, lifecycle hooks, and presigned uploads
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @veloxts/core@0.6.92
|
|
19
|
+
- @veloxts/router@0.6.92
|
|
20
|
+
|
|
3
21
|
## 0.6.91
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/GUIDE.md
CHANGED
|
@@ -86,6 +86,45 @@ const adminWithPermission = procedure()
|
|
|
86
86
|
.mutation(handler);
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
## Resource API Integration
|
|
90
|
+
|
|
91
|
+
Guards work seamlessly with the Resource API for context-dependent outputs:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { resource, resourceSchema } from '@veloxts/router';
|
|
95
|
+
import { authenticatedNarrow, adminNarrow } from '@veloxts/auth';
|
|
96
|
+
|
|
97
|
+
const UserSchema = resourceSchema()
|
|
98
|
+
.public('id', z.string())
|
|
99
|
+
.public('name', z.string())
|
|
100
|
+
.authenticated('email', z.string())
|
|
101
|
+
.admin('internalNotes', z.string().nullable())
|
|
102
|
+
.build();
|
|
103
|
+
|
|
104
|
+
// Anonymous - returns { id, name }
|
|
105
|
+
const getPublicUser = procedure()
|
|
106
|
+
.query(async ({ input, ctx }) => {
|
|
107
|
+
const user = await ctx.db.user.findUnique({ where: { id: input.id } });
|
|
108
|
+
return resource(user, UserSchema).forAnonymous();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Authenticated - returns { id, name, email }
|
|
112
|
+
const getUser = procedure()
|
|
113
|
+
.guardNarrow(authenticatedNarrow)
|
|
114
|
+
.query(async ({ input, ctx }) => {
|
|
115
|
+
const user = await ctx.db.user.findUnique({ where: { id: input.id } });
|
|
116
|
+
return resource(user, UserSchema).for(ctx); // Auto-detects level
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Admin - returns all fields
|
|
120
|
+
const getFullUser = procedure()
|
|
121
|
+
.guardNarrow(adminNarrow)
|
|
122
|
+
.query(async ({ input, ctx }) => {
|
|
123
|
+
const user = await ctx.db.user.findUnique({ where: { id: input.id } });
|
|
124
|
+
return resource(user, UserSchema).forAdmin();
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
89
128
|
## Password Hashing
|
|
90
129
|
|
|
91
130
|
```typescript
|
|
@@ -5,18 +5,26 @@
|
|
|
5
5
|
* When using `guardNarrow(authenticatedNarrow)`, the context type
|
|
6
6
|
* is narrowed to guarantee `ctx.user` is non-null.
|
|
7
7
|
*
|
|
8
|
+
* Additionally, these guards add phantom type tags for use with the
|
|
9
|
+
* Resource API, enabling context-dependent output types.
|
|
10
|
+
*
|
|
8
11
|
* EXPERIMENTAL: This API may change. The current recommended approach
|
|
9
12
|
* is to use middleware for context type extension.
|
|
10
13
|
*
|
|
11
14
|
* @module auth/guards-narrowing
|
|
12
15
|
*/
|
|
16
|
+
import type { AccessLevel, ADMIN, AUTHENTICATED, TaggedContext } from '@veloxts/router';
|
|
13
17
|
import type { AuthContext, GuardFunction, User } from './types.js';
|
|
18
|
+
export type { AccessLevel, ADMIN, AUTHENTICATED, TaggedContext };
|
|
14
19
|
/**
|
|
15
20
|
* A guard that narrows the context type after passing.
|
|
16
21
|
*
|
|
17
22
|
* The `_narrows` phantom type indicates what the guard guarantees
|
|
18
23
|
* about the context after it passes.
|
|
19
24
|
*
|
|
25
|
+
* The `accessLevel` property is used by the procedure builder to
|
|
26
|
+
* automatically set `ctx.__accessLevel` for resource auto-projection.
|
|
27
|
+
*
|
|
20
28
|
* @template TRequired - Context properties required to run the guard
|
|
21
29
|
* @template TGuaranteed - Context properties guaranteed after guard passes
|
|
22
30
|
*/
|
|
@@ -35,18 +43,41 @@ export interface NarrowingGuard<TRequired, TGuaranteed> {
|
|
|
35
43
|
* @internal
|
|
36
44
|
*/
|
|
37
45
|
readonly _narrows: TGuaranteed;
|
|
46
|
+
/**
|
|
47
|
+
* Runtime access level for automatic resource projection.
|
|
48
|
+
*
|
|
49
|
+
* When set, the procedure builder will automatically assign this
|
|
50
|
+
* value to `ctx.__accessLevel` after the guard passes, enabling
|
|
51
|
+
* auto-projection with `.resource()`.
|
|
52
|
+
*/
|
|
53
|
+
accessLevel?: AccessLevel;
|
|
38
54
|
}
|
|
39
55
|
/**
|
|
40
56
|
* Context type with a guaranteed authenticated user.
|
|
41
57
|
*
|
|
42
58
|
* After `authenticatedNarrow` passes, the context is narrowed to this type.
|
|
59
|
+
* Includes a phantom tag for the Resource API.
|
|
43
60
|
*/
|
|
44
|
-
export interface AuthenticatedContext {
|
|
61
|
+
export interface AuthenticatedContext extends TaggedContext<typeof AUTHENTICATED> {
|
|
45
62
|
auth: AuthContext & {
|
|
46
63
|
isAuthenticated: true;
|
|
47
64
|
};
|
|
48
65
|
user: User;
|
|
49
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Context type with a guaranteed user having admin role.
|
|
69
|
+
*
|
|
70
|
+
* After `adminNarrow` passes, the context is narrowed to this type.
|
|
71
|
+
* Includes a phantom tag for the Resource API.
|
|
72
|
+
*/
|
|
73
|
+
export interface AdminContext extends TaggedContext<typeof ADMIN> {
|
|
74
|
+
auth: AuthContext & {
|
|
75
|
+
isAuthenticated: true;
|
|
76
|
+
};
|
|
77
|
+
user: User & {
|
|
78
|
+
roles: string[];
|
|
79
|
+
};
|
|
80
|
+
}
|
|
50
81
|
/**
|
|
51
82
|
* Context type with a guaranteed user having specific roles.
|
|
52
83
|
*/
|
|
@@ -88,6 +119,30 @@ export interface RoleNarrowedContext {
|
|
|
88
119
|
export declare const authenticatedNarrow: NarrowingGuard<{
|
|
89
120
|
auth?: AuthContext;
|
|
90
121
|
}, AuthenticatedContext>;
|
|
122
|
+
/**
|
|
123
|
+
* Admin guard with type narrowing and phantom tag.
|
|
124
|
+
*
|
|
125
|
+
* When used with `guardNarrow()`, narrows `ctx.user` to a User with admin role
|
|
126
|
+
* and tags the context with ADMIN for use with the Resource API.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* import { adminNarrow } from '@veloxts/auth';
|
|
131
|
+
* import { resource, UserSchema } from '@veloxts/router';
|
|
132
|
+
*
|
|
133
|
+
* procedure()
|
|
134
|
+
* .guardNarrow(adminNarrow)
|
|
135
|
+
* .query(({ ctx }) => {
|
|
136
|
+
* // ctx.user is typed as User with roles: string[]
|
|
137
|
+
* // When used with resource(), returns all fields including admin-only
|
|
138
|
+
* const user = await ctx.db.user.findUnique({ where: { id } });
|
|
139
|
+
* return resource(user, UserSchema).forAdmin();
|
|
140
|
+
* });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export declare const adminNarrow: NarrowingGuard<{
|
|
144
|
+
user?: User;
|
|
145
|
+
}, AdminContext>;
|
|
91
146
|
/**
|
|
92
147
|
* Creates a role-checking guard with type narrowing.
|
|
93
148
|
*
|
package/dist/guards-narrowing.js
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* When using `guardNarrow(authenticatedNarrow)`, the context type
|
|
6
6
|
* is narrowed to guarantee `ctx.user` is non-null.
|
|
7
7
|
*
|
|
8
|
+
* Additionally, these guards add phantom type tags for use with the
|
|
9
|
+
* Resource API, enabling context-dependent output types.
|
|
10
|
+
*
|
|
8
11
|
* EXPERIMENTAL: This API may change. The current recommended approach
|
|
9
12
|
* is to use middleware for context type extension.
|
|
10
13
|
*
|
|
@@ -49,6 +52,36 @@ export const authenticatedNarrow = {
|
|
|
49
52
|
// Phantom type: value is never used at runtime, only carries type info.
|
|
50
53
|
// The `undefined as unknown as T` pattern is standard for phantom types.
|
|
51
54
|
_narrows: undefined,
|
|
55
|
+
// Runtime access level for auto-projection with .resource()
|
|
56
|
+
accessLevel: 'authenticated',
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Admin guard with type narrowing and phantom tag.
|
|
60
|
+
*
|
|
61
|
+
* When used with `guardNarrow()`, narrows `ctx.user` to a User with admin role
|
|
62
|
+
* and tags the context with ADMIN for use with the Resource API.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* import { adminNarrow } from '@veloxts/auth';
|
|
67
|
+
* import { resource, UserSchema } from '@veloxts/router';
|
|
68
|
+
*
|
|
69
|
+
* procedure()
|
|
70
|
+
* .guardNarrow(adminNarrow)
|
|
71
|
+
* .query(({ ctx }) => {
|
|
72
|
+
* // ctx.user is typed as User with roles: string[]
|
|
73
|
+
* // When used with resource(), returns all fields including admin-only
|
|
74
|
+
* const user = await ctx.db.user.findUnique({ where: { id } });
|
|
75
|
+
* return resource(user, UserSchema).forAdmin();
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export const adminNarrow = {
|
|
80
|
+
...hasRoleBase('admin'),
|
|
81
|
+
// Phantom type: carries type info for guardNarrow() and Resource API
|
|
82
|
+
_narrows: undefined,
|
|
83
|
+
// Runtime access level for auto-projection with .resource()
|
|
84
|
+
accessLevel: 'admin',
|
|
52
85
|
};
|
|
53
86
|
/**
|
|
54
87
|
* Creates a role-checking guard with type narrowing.
|
package/dist/index.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ export type { TokenStore } from './jwt.js';
|
|
|
15
15
|
export { createInMemoryTokenStore, generateTokenId, isValidTimespan, JwtManager, jwtManager, parseTimeToSeconds, validateTokenExpiration, } from './jwt.js';
|
|
16
16
|
export type { EnhancedTokenStore, EnhancedTokenStoreOptions } from './token-store.js';
|
|
17
17
|
export { createEnhancedTokenStore, DEFAULT_ALLOWED_ROLES, parseUserRoles, } from './token-store.js';
|
|
18
|
-
export type { AuthenticatedContext, InferNarrowedContext, NarrowingGuard, RoleNarrowedContext, } from './guards-narrowing.js';
|
|
19
|
-
export { authenticatedNarrow, hasRoleNarrow } from './guards-narrowing.js';
|
|
18
|
+
export type { ADMIN, AdminContext, AUTHENTICATED, AuthenticatedContext, InferNarrowedContext, NarrowingGuard, RoleNarrowedContext, TaggedContext, } from './guards-narrowing.js';
|
|
19
|
+
export { adminNarrow, authenticatedNarrow, hasRoleNarrow, } from './guards-narrowing.js';
|
|
20
20
|
export { DEFAULT_HASH_CONFIG, hashPassword, PasswordHasher, passwordHasher, verifyPassword, } from './hash.js';
|
|
21
21
|
export type { GuardBuilder } from './guards.js';
|
|
22
22
|
export { allOf, anyOf, authenticated, defineGuard, emailVerified, executeGuard, executeGuards, guard, hasAnyPermission, hasPermission, hasRole, not, userCan, } from './guards.js';
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ export { AuthError } from './types.js';
|
|
|
18
18
|
export { AUTH_REGISTERED, checkDoubleRegistration, decorateAuth, getRequestAuth, getRequestUser, setRequestAuth, } from './decoration.js';
|
|
19
19
|
export { createInMemoryTokenStore, generateTokenId, isValidTimespan, JwtManager, jwtManager, parseTimeToSeconds, validateTokenExpiration, } from './jwt.js';
|
|
20
20
|
export { createEnhancedTokenStore, DEFAULT_ALLOWED_ROLES, parseUserRoles, } from './token-store.js';
|
|
21
|
-
export { authenticatedNarrow, hasRoleNarrow } from './guards-narrowing.js';
|
|
21
|
+
export { adminNarrow, authenticatedNarrow, hasRoleNarrow, } from './guards-narrowing.js';
|
|
22
22
|
// ============================================================================
|
|
23
23
|
// Password Hashing
|
|
24
24
|
// ============================================================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/auth",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.93",
|
|
4
4
|
"description": "Authentication and authorization system for VeloxTS framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@fastify/cookie": "11.0.2",
|
|
63
63
|
"fastify": "5.7.2",
|
|
64
|
-
"@veloxts/core": "0.6.
|
|
65
|
-
"@veloxts/router": "0.6.
|
|
64
|
+
"@veloxts/core": "0.6.93",
|
|
65
|
+
"@veloxts/router": "0.6.93"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"argon2": ">=0.30.0",
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
"fastify-plugin": "5.1.0",
|
|
87
87
|
"typescript": "5.9.3",
|
|
88
88
|
"vitest": "4.0.18",
|
|
89
|
-
"@veloxts/
|
|
90
|
-
"@veloxts/
|
|
89
|
+
"@veloxts/testing": "0.6.93",
|
|
90
|
+
"@veloxts/validation": "0.6.93"
|
|
91
91
|
},
|
|
92
92
|
"keywords": [
|
|
93
93
|
"velox",
|