@shipfox/api-auth 7.0.1 → 7.1.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +28 -0
- package/README.md +19 -0
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js +38 -21
- package/dist/core/auth.js.map +1 -1
- package/dist/core/entities/refresh-token.d.ts +1 -0
- package/dist/core/entities/refresh-token.d.ts.map +1 -1
- package/dist/core/entities/refresh-token.js.map +1 -1
- package/dist/core/jwt.d.ts +2 -0
- package/dist/core/jwt.d.ts.map +1 -1
- package/dist/core/jwt.js +3 -1
- package/dist/core/jwt.js.map +1 -1
- package/dist/db/db.d.ts +34 -0
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/refresh-tokens.d.ts +9 -0
- package/dist/db/refresh-tokens.d.ts.map +1 -1
- package/dist/db/refresh-tokens.js +14 -0
- package/dist/db/refresh-tokens.js.map +1 -1
- package/dist/db/schema/refresh-tokens.d.ts +17 -0
- package/dist/db/schema/refresh-tokens.d.ts.map +1 -1
- package/dist/db/schema/refresh-tokens.js +4 -0
- package/dist/db/schema/refresh-tokens.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/presentation/auth/jwt-auth.d.ts +14 -1
- package/dist/presentation/auth/jwt-auth.d.ts.map +1 -1
- package/dist/presentation/auth/jwt-auth.js +34 -0
- package/dist/presentation/auth/jwt-auth.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0000_initial.sql +2 -0
- package/drizzle/meta/0000_snapshot.json +29 -0
- package/package.json +9 -23
- package/src/core/auth.test.ts +41 -0
- package/src/core/auth.ts +36 -19
- package/src/core/entities/refresh-token.ts +1 -0
- package/src/core/jwt.ts +3 -0
- package/src/db/refresh-tokens.test.ts +42 -0
- package/src/db/refresh-tokens.ts +42 -0
- package/src/db/schema/refresh-tokens.ts +6 -0
- package/src/index.ts +7 -1
- package/src/presentation/auth/jwt-auth.test.ts +102 -1
- package/src/presentation/auth/jwt-auth.ts +55 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -6,13 +6,27 @@ import {
|
|
|
6
6
|
type UserContext,
|
|
7
7
|
} from '@shipfox/api-auth-context';
|
|
8
8
|
import {userAccessTokenKey} from '@shipfox/node-auth-root-key';
|
|
9
|
-
import type
|
|
9
|
+
import {type AuthMethod, ClientError} from '@shipfox/node-fastify';
|
|
10
10
|
import type {FastifyRequest} from 'fastify';
|
|
11
|
+
import type {RefreshToken} from '#core/entities/refresh-token.js';
|
|
12
|
+
import type {User} from '#core/entities/user.js';
|
|
13
|
+
import type {UserTokenClaims} from '#core/jwt.js';
|
|
11
14
|
import {verifyUserToken} from '#core/jwt.js';
|
|
15
|
+
import {findActiveRefreshSession} from '#db/refresh-tokens.js';
|
|
12
16
|
import {createBearerTokenAuthMethod} from './bearer-token-auth.js';
|
|
13
17
|
|
|
18
|
+
const AUTHENTICATED_SESSION_CONTEXT_KEY = Symbol.for('@shipfox/api-auth/session');
|
|
19
|
+
|
|
14
20
|
export type ClientContext = UserContext;
|
|
15
21
|
|
|
22
|
+
export type UserId = User['id'];
|
|
23
|
+
export type RefreshSessionId = RefreshToken['sessionId'];
|
|
24
|
+
|
|
25
|
+
export type AuthenticatedSessionContext = {
|
|
26
|
+
userId: UserId;
|
|
27
|
+
refreshSessionId: RefreshSessionId;
|
|
28
|
+
};
|
|
29
|
+
|
|
16
30
|
export interface CreateJwtAuthMethodOptions {
|
|
17
31
|
secret: string;
|
|
18
32
|
}
|
|
@@ -21,6 +35,45 @@ export function getClientContext(request: FastifyRequest): ClientContext | null
|
|
|
21
35
|
return getUserContext(request);
|
|
22
36
|
}
|
|
23
37
|
|
|
38
|
+
function setAuthenticatedSessionContext(request: FastifyRequest, claims: UserTokenClaims): void {
|
|
39
|
+
(request as unknown as Record<symbol, unknown>)[AUTHENTICATED_SESSION_CONTEXT_KEY] = {
|
|
40
|
+
userId: claims.sub,
|
|
41
|
+
refreshSessionId: claims.refreshSessionId,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getAuthenticatedSessionTokenContext(request: FastifyRequest): {
|
|
46
|
+
userId: UserId;
|
|
47
|
+
refreshSessionId: RefreshSessionId | undefined;
|
|
48
|
+
} | null {
|
|
49
|
+
return (
|
|
50
|
+
((request as unknown as Record<symbol, unknown>)[AUTHENTICATED_SESSION_CONTEXT_KEY] as
|
|
51
|
+
| {userId: UserId; refreshSessionId: RefreshSessionId | undefined}
|
|
52
|
+
| undefined) ?? null
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Resolves the active refresh session backing an authenticated user request.
|
|
58
|
+
* The session check intentionally happens only for consumers that need browser-session binding.
|
|
59
|
+
*/
|
|
60
|
+
export async function getAuthenticatedSessionContext(
|
|
61
|
+
request: FastifyRequest,
|
|
62
|
+
): Promise<AuthenticatedSessionContext> {
|
|
63
|
+
const client = getClientContext(request);
|
|
64
|
+
const token = getAuthenticatedSessionTokenContext(request);
|
|
65
|
+
if (!client || !token || token.userId !== client.userId || !token.refreshSessionId)
|
|
66
|
+
throw new ClientError('Invalid or expired token', 'unauthorized', {status: 401});
|
|
67
|
+
|
|
68
|
+
const session = await findActiveRefreshSession({
|
|
69
|
+
sessionId: token.refreshSessionId,
|
|
70
|
+
userId: client.userId,
|
|
71
|
+
});
|
|
72
|
+
if (!session) throw new ClientError('Invalid or expired token', 'unauthorized', {status: 401});
|
|
73
|
+
|
|
74
|
+
return {userId: client.userId, refreshSessionId: session.sessionId};
|
|
75
|
+
}
|
|
76
|
+
|
|
24
77
|
export function createJwtAuthMethod(): AuthMethod {
|
|
25
78
|
return createBearerTokenAuthMethod({
|
|
26
79
|
name: AUTH_USER,
|
|
@@ -34,6 +87,7 @@ export function createJwtAuthMethod(): AuthMethod {
|
|
|
34
87
|
memberships: claims.memberships,
|
|
35
88
|
});
|
|
36
89
|
setUserContext(request, clientContext);
|
|
90
|
+
setAuthenticatedSessionContext(request, claims);
|
|
37
91
|
},
|
|
38
92
|
});
|
|
39
93
|
}
|