@dainprotocol/service-sdk 1.2.1 → 1.2.2
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/dist/client/client-auth.d.ts +90 -9
- package/dist/client/client-auth.js +177 -90
- package/dist/client/client-auth.js.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/service-auth.d.ts +61 -0
- package/dist/client/service-auth.js +93 -0
- package/dist/client/service-auth.js.map +1 -0
- package/dist/client/user-auth.d.ts +74 -0
- package/dist/client/user-auth.js +137 -0
- package/dist/client/user-auth.js.map +1 -0
- package/dist/service/auth.d.ts +25 -35
- package/dist/service/auth.js +76 -77
- package/dist/service/auth.js.map +1 -1
- package/dist/service/server.js +52 -66
- package/dist/service/server.js.map +1 -1
- package/dist/service/types.d.ts +6 -0
- package/package.json +3 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//File: src/client/service-auth.ts
|
|
3
|
+
/**
|
|
4
|
+
* Service/Agent Authentication - Legacy Keypair-based
|
|
5
|
+
*
|
|
6
|
+
* This class is for SERVICE and AGENT authentication using legacy keypair-based signatures.
|
|
7
|
+
* End users should NOT use this class - they must use DainUserAuth with JWT tokens.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.DainServiceAuth = void 0;
|
|
11
|
+
const client_auth_1 = require("./client-auth");
|
|
12
|
+
/**
|
|
13
|
+
* DainServiceAuth - Legacy keypair-based authentication for services and agents
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // Authenticate as a service with API key
|
|
18
|
+
* const serviceAuth = new DainServiceAuth({
|
|
19
|
+
* apiKey: "sk_agent_org_123_agent_456_<base58key>"
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // OR with individual components
|
|
23
|
+
* const serviceAuth = new DainServiceAuth({
|
|
24
|
+
* privateKeyBase58: "49bhyNKM...",
|
|
25
|
+
* agentId: "agent_456",
|
|
26
|
+
* orgId: "org_123"
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
class DainServiceAuth extends client_auth_1.DainClientAuth {
|
|
31
|
+
constructor(config) {
|
|
32
|
+
if (!config.apiKey && !(config.privateKeyBase58 && config.agentId && config.orgId)) {
|
|
33
|
+
throw new Error('Invalid service authentication configuration.\n' +
|
|
34
|
+
'Provide either:\n' +
|
|
35
|
+
' - apiKey: "sk_agent_org_<orgId>_<agentId>_<keypair>"\n' +
|
|
36
|
+
' OR\n' +
|
|
37
|
+
' - privateKeyBase58, agentId, and orgId\n\n' +
|
|
38
|
+
'Note: This is for SERVICES and AGENTS only.\n' +
|
|
39
|
+
'If you are authenticating as a user, use DainUserAuth with a JWT token instead.');
|
|
40
|
+
}
|
|
41
|
+
// Call parent with legacy auth config
|
|
42
|
+
super({
|
|
43
|
+
apiKey: config.apiKey,
|
|
44
|
+
privateKeyBase58: config.privateKeyBase58,
|
|
45
|
+
agentId: config.agentId,
|
|
46
|
+
orgId: config.orgId,
|
|
47
|
+
smartAccountPDA: config.smartAccountPDA,
|
|
48
|
+
webhookUrl: config.webhookUrl,
|
|
49
|
+
});
|
|
50
|
+
// Verify auth method is legacy
|
|
51
|
+
if (this.getAuthMethod() !== 'legacy') {
|
|
52
|
+
throw new Error('DainServiceAuth must use legacy authentication');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get the service's agent ID
|
|
57
|
+
*/
|
|
58
|
+
getServiceAgentId() {
|
|
59
|
+
const agentId = this.getAgentId();
|
|
60
|
+
if (!agentId) {
|
|
61
|
+
throw new Error('Agent ID not available');
|
|
62
|
+
}
|
|
63
|
+
return agentId;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the service's organization ID
|
|
67
|
+
*/
|
|
68
|
+
getServiceOrgId() {
|
|
69
|
+
const orgId = this.getOrgId();
|
|
70
|
+
if (!orgId) {
|
|
71
|
+
throw new Error('Organization ID not available');
|
|
72
|
+
}
|
|
73
|
+
return orgId;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Override to prevent JWT methods
|
|
77
|
+
* @deprecated Not supported for service authentication
|
|
78
|
+
*/
|
|
79
|
+
getSmartAccountId() {
|
|
80
|
+
throw new Error('getSmartAccountId() is not supported for service authentication.\n' +
|
|
81
|
+
'Use getServiceAgentId() instead.');
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Override to prevent JWT methods
|
|
85
|
+
* @deprecated Not supported for service authentication
|
|
86
|
+
*/
|
|
87
|
+
getJWT() {
|
|
88
|
+
throw new Error('getJWT() is not supported for service authentication.\n' +
|
|
89
|
+
'Services use keypair-based authentication, not JWT.');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.DainServiceAuth = DainServiceAuth;
|
|
93
|
+
//# sourceMappingURL=service-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-auth.js","sourceRoot":"","sources":["../../src/client/service-auth.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC;;;;;GAKG;;;AAEH,+CAA+C;AAqB/C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAa,eAAgB,SAAQ,4BAAc;IACjD,YAAY,MAA6B;QACvC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACnF,MAAM,IAAI,KAAK,CACb,iDAAiD;gBACjD,mBAAmB;gBACnB,0DAA0D;gBAC1D,QAAQ;gBACR,8CAA8C;gBAC9C,+CAA+C;gBAC/C,iFAAiF,CAClF,CAAC;QACJ,CAAC;QAED,sCAAsC;QACtC,KAAK,CAAC;YACJ,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;QAEH,+BAA+B;QAC/B,IAAI,IAAI,CAAC,aAAa,EAAE,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,eAAe;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,iBAAiB;QACf,MAAM,IAAI,KAAK,CACb,oEAAoE;YACpE,kCAAkC,CACnC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,MAAM,IAAI,KAAK,CACb,yDAAyD;YACzD,qDAAqD,CACtD,CAAC;IACJ,CAAC;CACF;AAzED,0CAyEC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Authentication - JWT ONLY
|
|
3
|
+
*
|
|
4
|
+
* Users authenticate with JWT tokens from DAIN ID OAuth.
|
|
5
|
+
* NO orgId, NO agentId, NO keypair - completely removed for users.
|
|
6
|
+
*/
|
|
7
|
+
export interface DainUserAuthConfig {
|
|
8
|
+
/** JWT access token from DAIN ID OAuth */
|
|
9
|
+
jwt: string;
|
|
10
|
+
/** Smart Account ID (optional, will be extracted from JWT if not provided) */
|
|
11
|
+
smartAccountId?: string;
|
|
12
|
+
/** Smart Account PDA on Solana (optional) */
|
|
13
|
+
smartAccountPDA?: string;
|
|
14
|
+
/** Webhook URL for async operations (optional) */
|
|
15
|
+
webhookUrl?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* DainUserAuth - JWT-only authentication for end users
|
|
19
|
+
*
|
|
20
|
+
* Users have:
|
|
21
|
+
* - JWT token (for authentication)
|
|
22
|
+
* - Smart Account ID (their unique identifier)
|
|
23
|
+
* - NO orgId, NO agentId, NO keypair
|
|
24
|
+
*/
|
|
25
|
+
export declare class DainUserAuth {
|
|
26
|
+
private jwt;
|
|
27
|
+
private smartAccountId;
|
|
28
|
+
private smartAccountPDA?;
|
|
29
|
+
private webhookUrl?;
|
|
30
|
+
constructor(config: DainUserAuthConfig);
|
|
31
|
+
/**
|
|
32
|
+
* Decode JWT payload (without verification)
|
|
33
|
+
*/
|
|
34
|
+
private decodeJWTPayload;
|
|
35
|
+
/**
|
|
36
|
+
* Sign request - NOT NEEDED for JWT, returns empty
|
|
37
|
+
*/
|
|
38
|
+
signRequest(_method: string, _path: string, _body: string): Promise<{
|
|
39
|
+
signature: string;
|
|
40
|
+
timestamp: string;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Get headers for HTTP requests
|
|
44
|
+
*/
|
|
45
|
+
getHeaders(_signature: string, _timestamp: string): Record<string, string>;
|
|
46
|
+
/**
|
|
47
|
+
* Get the user's smart account ID
|
|
48
|
+
*/
|
|
49
|
+
getSmartAccountId(): string;
|
|
50
|
+
/**
|
|
51
|
+
* Get JWT token
|
|
52
|
+
*/
|
|
53
|
+
getJWT(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Get smart account PDA
|
|
56
|
+
*/
|
|
57
|
+
getSmartAccountPDA(): string | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Get webhook URL
|
|
60
|
+
*/
|
|
61
|
+
getWebhookUrl(): string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Check if using JWT authentication (always true for users)
|
|
64
|
+
*/
|
|
65
|
+
isJWT(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Serialize user auth
|
|
68
|
+
*/
|
|
69
|
+
serialize(): string;
|
|
70
|
+
/**
|
|
71
|
+
* Deserialize user auth
|
|
72
|
+
*/
|
|
73
|
+
static deserialize(serialized: string): DainUserAuth;
|
|
74
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//File: src/client/user-auth.ts
|
|
3
|
+
/**
|
|
4
|
+
* User Authentication - JWT ONLY
|
|
5
|
+
*
|
|
6
|
+
* Users authenticate with JWT tokens from DAIN ID OAuth.
|
|
7
|
+
* NO orgId, NO agentId, NO keypair - completely removed for users.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.DainUserAuth = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* DainUserAuth - JWT-only authentication for end users
|
|
13
|
+
*
|
|
14
|
+
* Users have:
|
|
15
|
+
* - JWT token (for authentication)
|
|
16
|
+
* - Smart Account ID (their unique identifier)
|
|
17
|
+
* - NO orgId, NO agentId, NO keypair
|
|
18
|
+
*/
|
|
19
|
+
class DainUserAuth {
|
|
20
|
+
jwt;
|
|
21
|
+
smartAccountId;
|
|
22
|
+
smartAccountPDA;
|
|
23
|
+
webhookUrl;
|
|
24
|
+
constructor(config) {
|
|
25
|
+
if (!config.jwt) {
|
|
26
|
+
throw new Error('JWT token is required for user authentication');
|
|
27
|
+
}
|
|
28
|
+
this.jwt = config.jwt;
|
|
29
|
+
// Extract smartAccountId from config or decode from JWT
|
|
30
|
+
if (config.smartAccountId) {
|
|
31
|
+
this.smartAccountId = config.smartAccountId;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const payload = this.decodeJWTPayload(config.jwt);
|
|
35
|
+
this.smartAccountId = payload.smart_account_id || payload.sub;
|
|
36
|
+
}
|
|
37
|
+
this.smartAccountPDA = config.smartAccountPDA;
|
|
38
|
+
this.webhookUrl = config.webhookUrl;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Decode JWT payload (without verification)
|
|
42
|
+
*/
|
|
43
|
+
decodeJWTPayload(jwt) {
|
|
44
|
+
const parts = jwt.split('.');
|
|
45
|
+
if (parts.length !== 3) {
|
|
46
|
+
throw new Error('Invalid JWT format');
|
|
47
|
+
}
|
|
48
|
+
const payload = Buffer.from(parts[1], 'base64').toString('utf-8');
|
|
49
|
+
return JSON.parse(payload);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Sign request - NOT NEEDED for JWT, returns empty
|
|
53
|
+
*/
|
|
54
|
+
async signRequest(_method, _path, _body) {
|
|
55
|
+
return { signature: '', timestamp: '' };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get headers for HTTP requests
|
|
59
|
+
*/
|
|
60
|
+
getHeaders(_signature, _timestamp) {
|
|
61
|
+
const headers = {
|
|
62
|
+
"Authorization": `Bearer ${this.jwt}`,
|
|
63
|
+
};
|
|
64
|
+
if (this.smartAccountPDA) {
|
|
65
|
+
headers["X-DAIN-SMART-ACCOUNT-PDA"] = this.smartAccountPDA;
|
|
66
|
+
}
|
|
67
|
+
if (this.webhookUrl) {
|
|
68
|
+
headers["X-DAIN-WEBHOOK-URL"] = this.webhookUrl;
|
|
69
|
+
}
|
|
70
|
+
return headers;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the user's smart account ID
|
|
74
|
+
*/
|
|
75
|
+
getSmartAccountId() {
|
|
76
|
+
return this.smartAccountId;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get JWT token
|
|
80
|
+
*/
|
|
81
|
+
getJWT() {
|
|
82
|
+
return this.jwt;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get smart account PDA
|
|
86
|
+
*/
|
|
87
|
+
getSmartAccountPDA() {
|
|
88
|
+
return this.smartAccountPDA;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get webhook URL
|
|
92
|
+
*/
|
|
93
|
+
getWebhookUrl() {
|
|
94
|
+
return this.webhookUrl;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if using JWT authentication (always true for users)
|
|
98
|
+
*/
|
|
99
|
+
isJWT() {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Serialize user auth
|
|
104
|
+
*/
|
|
105
|
+
serialize() {
|
|
106
|
+
const data = {
|
|
107
|
+
authMethod: 'jwt',
|
|
108
|
+
jwt: this.jwt,
|
|
109
|
+
smartAccountId: this.smartAccountId,
|
|
110
|
+
smartAccountPDA: this.smartAccountPDA,
|
|
111
|
+
webhookUrl: this.webhookUrl
|
|
112
|
+
};
|
|
113
|
+
return Buffer.from(JSON.stringify(data)).toString('base64');
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Deserialize user auth
|
|
117
|
+
*/
|
|
118
|
+
static deserialize(serialized) {
|
|
119
|
+
try {
|
|
120
|
+
const data = JSON.parse(Buffer.from(serialized, 'base64').toString());
|
|
121
|
+
if (data.authMethod !== 'jwt') {
|
|
122
|
+
throw new Error('Invalid auth method for user');
|
|
123
|
+
}
|
|
124
|
+
return new DainUserAuth({
|
|
125
|
+
jwt: data.jwt,
|
|
126
|
+
smartAccountId: data.smartAccountId,
|
|
127
|
+
smartAccountPDA: data.smartAccountPDA,
|
|
128
|
+
webhookUrl: data.webhookUrl
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new Error('Failed to deserialize DainUserAuth: ' + error.message);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.DainUserAuth = DainUserAuth;
|
|
137
|
+
//# sourceMappingURL=user-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-auth.js","sourceRoot":"","sources":["../../src/client/user-auth.ts"],"names":[],"mappings":"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"}
|
package/dist/service/auth.d.ts
CHANGED
|
@@ -1,48 +1,38 @@
|
|
|
1
|
+
export declare function addressToPublicKeyBytes(address: string): Uint8Array;
|
|
2
|
+
export declare function signatureToBytes(signature: string): Uint8Array;
|
|
3
|
+
export declare function verifySignature(signature: string, message: string, address: string): boolean;
|
|
4
|
+
export declare function sanitizeHeaders(headers: Record<string, unknown>): Record<string, string>;
|
|
5
|
+
export declare function signResponse(privateKey: Uint8Array, responseBody: string): {
|
|
6
|
+
signature: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function verifyResponse(publicKey: Uint8Array, responseBody: string, signature: string, timestamp: string): boolean;
|
|
10
|
+
export declare function verifyRequestSignature(signature: string, method: string, path: string, headers: Record<string, string>, body: string, address: string, smartAccountPDA: string): boolean;
|
|
11
|
+
export declare function isValidSolanaAddress(address: string): boolean;
|
|
1
12
|
/**
|
|
2
|
-
* JWT
|
|
13
|
+
* JWT payload structure from DAIN ID OAuth
|
|
3
14
|
*/
|
|
4
|
-
export interface
|
|
15
|
+
export interface DainIDJWTPayload {
|
|
5
16
|
sub: string;
|
|
6
17
|
iss: string;
|
|
7
18
|
aud: string;
|
|
8
19
|
iat: number;
|
|
9
20
|
exp: number;
|
|
10
|
-
scope
|
|
11
|
-
smart_account_id
|
|
21
|
+
scope?: string[];
|
|
22
|
+
smart_account_id?: string;
|
|
12
23
|
}
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
/**
|
|
25
|
+
* JWT verification result
|
|
26
|
+
*/
|
|
27
|
+
export interface JWTVerificationResult {
|
|
28
|
+
valid: boolean;
|
|
29
|
+
payload?: DainIDJWTPayload;
|
|
15
30
|
smartAccountId?: string;
|
|
16
31
|
scope?: string[];
|
|
17
|
-
agentId?: string;
|
|
18
|
-
orgId?: string;
|
|
19
|
-
address?: string;
|
|
20
32
|
error?: string;
|
|
21
33
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Verify JWT token from DAIN ID
|
|
24
|
-
* This should be used with a public key fetched from DAIN ID's JWKS endpoint
|
|
25
|
-
*/
|
|
26
|
-
export declare function verifyJWT(token: string, publicKeyOrJWKS: string | any): Promise<AuthResult>;
|
|
27
|
-
/**
|
|
28
|
-
* Extract Bearer token from Authorization header
|
|
29
|
-
*/
|
|
30
34
|
export declare function extractBearerToken(authHeader: string | undefined): string | null;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* LEGACY AUTHENTICATION (for service-to-service)
|
|
37
|
-
*/
|
|
38
|
-
export declare function addressToPublicKeyBytes(address: string): Uint8Array;
|
|
39
|
-
export declare function signatureToBytes(signature: string): Uint8Array;
|
|
40
|
-
export declare function verifySignature(signature: string, message: string, address: string): boolean;
|
|
41
|
-
export declare function sanitizeHeaders(headers: Record<string, unknown>): Record<string, string>;
|
|
42
|
-
export declare function signResponse(privateKey: Uint8Array, responseBody: string): {
|
|
43
|
-
signature: string;
|
|
44
|
-
timestamp: string;
|
|
45
|
-
};
|
|
46
|
-
export declare function verifyResponse(publicKey: Uint8Array, responseBody: string, signature: string, timestamp: string): boolean;
|
|
47
|
-
export declare function verifyRequestSignature(signature: string, method: string, path: string, headers: Record<string, string>, body: string, address: string, smartAccountPDA?: string): boolean;
|
|
48
|
-
export declare function isValidSolanaAddress(address: string): boolean;
|
|
35
|
+
export declare function verifyJWT(token: string, publicKeyPEMOrUrl: string, options?: {
|
|
36
|
+
issuer?: string;
|
|
37
|
+
audience?: string;
|
|
38
|
+
}): Promise<JWTVerificationResult>;
|
package/dist/service/auth.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// File: src/service/auth.ts
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.verifyJWT = verifyJWT;
|
|
5
|
-
exports.extractBearerToken = extractBearerToken;
|
|
6
|
-
exports.hasRequiredScope = hasRequiredScope;
|
|
7
4
|
exports.addressToPublicKeyBytes = addressToPublicKeyBytes;
|
|
8
5
|
exports.signatureToBytes = signatureToBytes;
|
|
9
6
|
exports.verifySignature = verifySignature;
|
|
@@ -12,82 +9,14 @@ exports.signResponse = signResponse;
|
|
|
12
9
|
exports.verifyResponse = verifyResponse;
|
|
13
10
|
exports.verifyRequestSignature = verifyRequestSignature;
|
|
14
11
|
exports.isValidSolanaAddress = isValidSolanaAddress;
|
|
12
|
+
exports.extractBearerToken = extractBearerToken;
|
|
13
|
+
exports.verifyJWT = verifyJWT;
|
|
15
14
|
const tslib_1 = require("tslib");
|
|
16
15
|
const ed25519_1 = require("@noble/curves/ed25519");
|
|
17
16
|
const sha256_1 = require("@noble/hashes/sha256");
|
|
18
17
|
const utils_1 = require("@noble/hashes/utils");
|
|
19
18
|
const bs58_1 = tslib_1.__importDefault(require("bs58"));
|
|
20
|
-
|
|
21
|
-
* Verify JWT token from DAIN ID
|
|
22
|
-
* This should be used with a public key fetched from DAIN ID's JWKS endpoint
|
|
23
|
-
*/
|
|
24
|
-
async function verifyJWT(token, publicKeyOrJWKS) {
|
|
25
|
-
try {
|
|
26
|
-
// In a real implementation, use jsonwebtoken library
|
|
27
|
-
// For now, we'll decode without verification (services should implement proper verification)
|
|
28
|
-
const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
29
|
-
// Verify issuer
|
|
30
|
-
if (payload.iss !== 'dainid-oauth') {
|
|
31
|
-
return {
|
|
32
|
-
success: false,
|
|
33
|
-
error: 'Invalid issuer',
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
// Verify expiration
|
|
37
|
-
const now = Math.floor(Date.now() / 1000);
|
|
38
|
-
if (payload.exp && payload.exp < now) {
|
|
39
|
-
return {
|
|
40
|
-
success: false,
|
|
41
|
-
error: 'Token expired',
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
// Extract smart account ID
|
|
45
|
-
const smartAccountId = payload.smart_account_id || payload.sub;
|
|
46
|
-
if (!smartAccountId) {
|
|
47
|
-
return {
|
|
48
|
-
success: false,
|
|
49
|
-
error: 'Missing smart_account_id',
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
success: true,
|
|
54
|
-
smartAccountId,
|
|
55
|
-
scope: payload.scope || [],
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
return {
|
|
60
|
-
success: false,
|
|
61
|
-
error: error instanceof Error ? error.message : 'JWT verification failed',
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Extract Bearer token from Authorization header
|
|
67
|
-
*/
|
|
68
|
-
function extractBearerToken(authHeader) {
|
|
69
|
-
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
return authHeader.substring(7);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Check if token has required scope
|
|
76
|
-
*/
|
|
77
|
-
function hasRequiredScope(tokenScopes, requiredScope) {
|
|
78
|
-
return (tokenScopes.includes(requiredScope) ||
|
|
79
|
-
tokenScopes.includes('*') ||
|
|
80
|
-
tokenScopes.some((scope) => {
|
|
81
|
-
if (scope.endsWith('.*')) {
|
|
82
|
-
const prefix = scope.slice(0, -2);
|
|
83
|
-
return requiredScope.startsWith(prefix + '.');
|
|
84
|
-
}
|
|
85
|
-
return false;
|
|
86
|
-
}));
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* LEGACY AUTHENTICATION (for service-to-service)
|
|
90
|
-
*/
|
|
19
|
+
const jsonwebtoken_1 = tslib_1.__importDefault(require("jsonwebtoken"));
|
|
91
20
|
function addressToPublicKeyBytes(address) {
|
|
92
21
|
try {
|
|
93
22
|
return bs58_1.default.decode(address);
|
|
@@ -125,10 +54,10 @@ function sanitizeHeaders(headers) {
|
|
|
125
54
|
else if ((upperKey === "CONTENT-TYPE" || upperKey.startsWith("X-")) &&
|
|
126
55
|
Array.isArray(value) &&
|
|
127
56
|
value.length > 0) {
|
|
128
|
-
sanitizedHeaders[upperKey] = value.join(", ");
|
|
57
|
+
sanitizedHeaders[upperKey] = value.join(", "); // Convert array to comma-separated string
|
|
129
58
|
}
|
|
130
59
|
}
|
|
131
|
-
// Sort headers alphabetically
|
|
60
|
+
// Sort headers alphabetically by key
|
|
132
61
|
const sortedSanitizedHeaders = Object.keys(sanitizedHeaders)
|
|
133
62
|
.sort()
|
|
134
63
|
.reduce((acc, key) => {
|
|
@@ -155,12 +84,14 @@ function verifyResponse(publicKey, responseBody, signature, timestamp) {
|
|
|
155
84
|
}
|
|
156
85
|
}
|
|
157
86
|
function verifyRequestSignature(signature, method, path, headers, body, address, smartAccountPDA) {
|
|
87
|
+
//TODO smartAccountPDA check
|
|
158
88
|
const timestamp = headers["X-DAIN-TIMESTAMP"];
|
|
159
89
|
if (!timestamp) {
|
|
160
90
|
return false;
|
|
161
91
|
}
|
|
162
|
-
//
|
|
92
|
+
// remove x-dain-timestamp from headers
|
|
163
93
|
delete headers["X-DAIN-TIMESTAMP"];
|
|
94
|
+
//delete the signature from headers
|
|
164
95
|
delete headers["X-DAIN-SIGNATURE"];
|
|
165
96
|
const message = `${method.toUpperCase()}:${path}:${timestamp}:${body ? body : "{}"}`;
|
|
166
97
|
return verifySignature(signature, message, address);
|
|
@@ -174,4 +105,72 @@ function isValidSolanaAddress(address) {
|
|
|
174
105
|
return false;
|
|
175
106
|
}
|
|
176
107
|
}
|
|
108
|
+
// Simple JWKS cache (public key strings)
|
|
109
|
+
const jwksCache = new Map();
|
|
110
|
+
const CACHE_TTL = 3600000; // 1 hour
|
|
111
|
+
function extractBearerToken(authHeader) {
|
|
112
|
+
if (!authHeader)
|
|
113
|
+
return null;
|
|
114
|
+
const parts = authHeader.split(" ");
|
|
115
|
+
if (parts.length !== 2 || parts[0] !== "Bearer")
|
|
116
|
+
return null;
|
|
117
|
+
return parts[1];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Fetch public key from JWKS endpoint (with caching)
|
|
121
|
+
*/
|
|
122
|
+
async function fetchPublicKey(dainIdUrl) {
|
|
123
|
+
// Check cache
|
|
124
|
+
const cached = jwksCache.get(dainIdUrl);
|
|
125
|
+
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
|
126
|
+
return cached.publicKey;
|
|
127
|
+
}
|
|
128
|
+
// Fetch JWKS
|
|
129
|
+
const jwksUrl = `${dainIdUrl}/api/oauth/.well-known/jwks.json`;
|
|
130
|
+
const response = await fetch(jwksUrl);
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
throw new Error(`Failed to fetch JWKS: ${response.statusText}`);
|
|
133
|
+
}
|
|
134
|
+
const jwks = await response.json();
|
|
135
|
+
const key = jwks.keys[0]; // Use first key
|
|
136
|
+
// Convert JWK to PEM
|
|
137
|
+
const publicKey = jwkToPem(key);
|
|
138
|
+
// Cache it
|
|
139
|
+
jwksCache.set(dainIdUrl, { publicKey, timestamp: Date.now() });
|
|
140
|
+
return publicKey;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Convert JWK to PEM format (simple RSA only)
|
|
144
|
+
*/
|
|
145
|
+
function jwkToPem(jwk) {
|
|
146
|
+
const crypto = require("crypto");
|
|
147
|
+
const keyObject = crypto.createPublicKey({ key: jwk, format: "jwk" });
|
|
148
|
+
return keyObject.export({ type: "spki", format: "pem" });
|
|
149
|
+
}
|
|
150
|
+
async function verifyJWT(token, publicKeyPEMOrUrl, options) {
|
|
151
|
+
try {
|
|
152
|
+
// Fetch public key if URL provided
|
|
153
|
+
const publicKey = publicKeyPEMOrUrl.startsWith("http")
|
|
154
|
+
? await fetchPublicKey(publicKeyPEMOrUrl)
|
|
155
|
+
: publicKeyPEMOrUrl;
|
|
156
|
+
// Verify JWT
|
|
157
|
+
const payload = jsonwebtoken_1.default.verify(token, publicKey, {
|
|
158
|
+
algorithms: ["RS256"],
|
|
159
|
+
issuer: options?.issuer,
|
|
160
|
+
audience: options?.audience,
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
valid: true,
|
|
164
|
+
payload,
|
|
165
|
+
smartAccountId: payload.smart_account_id || payload.sub,
|
|
166
|
+
scope: payload.scope || [],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
return {
|
|
171
|
+
valid: false,
|
|
172
|
+
error: error instanceof Error ? error.message : "Invalid token",
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
177
176
|
//# sourceMappingURL=auth.js.map
|
package/dist/service/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/service/auth.ts"],"names":[],"mappings":";AAAA,4BAA4B;;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/service/auth.ts"],"names":[],"mappings":"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"}
|