-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsession-manager.service.ts
More file actions
100 lines (92 loc) · 2.45 KB
/
Copy pathsession-manager.service.ts
File metadata and controls
100 lines (92 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { Injectable, Inject } from '@nestjs/common';
import * as jwt from 'jsonwebtoken';
import { ApiModuleConfig, API_MODULE_CONFIG } from './api.config';
/**
* Payload structure for session tokens
*/
export interface SessionTokenPayload {
identifier: string;
authMethod: 'passkey' | 'mediation' | 'otp';
}
/**
* Result of session token verification
*/
export interface VerifySessionTokenResult {
valid: boolean;
payload?: SessionTokenPayload;
error?: string;
}
/**
* SessionManagerService - Handles session token generation and verification
*
* See README.md for more details.
*/
@Injectable()
export class SessionManagerService {
private readonly secret: string;
private readonly expiresIn: number;
constructor(@Inject(API_MODULE_CONFIG) config: ApiModuleConfig) {
this.secret = config.jwtSecret;
this.expiresIn = config.sessionTokenExpirySeconds || 60 * 60 * 12; // 12 hours
}
/**
* Generate a signed session token after successful authentication
*
* This token proves the user authenticated.
*
* @param identifier - Your application's user identifier
* @param authMethod - How the user authenticated ('passkey', 'mediation', or 'otp')
* @returns Signed JWT session token
*/
generateSessionToken(
identifier: string,
authMethod: 'passkey' | 'mediation' | 'otp',
): string {
const payload: SessionTokenPayload = {
identifier,
authMethod,
};
return jwt.sign(payload, this.secret, {
expiresIn: this.expiresIn,
issuer: 'custom-api',
subject: identifier,
});
}
/**
* Verify a session token
*
* @param token - The session token to verify
* @returns Verification result with payload if valid
*/
verifySessionToken(token: string): VerifySessionTokenResult {
try {
const payload = jwt.verify(token, this.secret, {
issuer: 'custom-api',
}) as SessionTokenPayload;
return {
valid: true,
payload: {
identifier: payload.identifier,
authMethod: payload.authMethod,
},
};
} catch (error) {
if (error instanceof jwt.TokenExpiredError) {
return {
valid: false,
error: 'Token expired',
};
}
if (error instanceof jwt.JsonWebTokenError) {
return {
valid: false,
error: 'Invalid token',
};
}
return {
valid: false,
error: 'Token verification failed',
};
}
}
}