@managesome/knotr-toolkit 0.8.6 → 0.8.7
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/backend/index.d.ts +2 -1
- package/dist/backend/index.d.ts.map +1 -1
- package/dist/backend/index.js +2 -0
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/service-auth.d.ts +54 -0
- package/dist/backend/service-auth.d.ts.map +1 -0
- package/dist/backend/service-auth.js +142 -0
- package/dist/backend/service-auth.js.map +1 -0
- package/dist/schemas/account.schema.d.ts +7 -4331
- package/dist/schemas/account.schema.d.ts.map +1 -1
- package/dist/schemas/chat.schema.d.ts +13 -4660
- package/dist/schemas/chat.schema.d.ts.map +1 -1
- package/dist/schemas/collaboration-request.schema.d.ts +8 -3917
- package/dist/schemas/collaboration-request.schema.d.ts.map +1 -1
- package/dist/schemas/company-review.schema.d.ts +7 -3421
- package/dist/schemas/company-review.schema.d.ts.map +1 -1
- package/dist/schemas/company.schema.d.ts +8 -6108
- package/dist/schemas/company.schema.d.ts.map +1 -1
- package/dist/schemas/contract.schema.d.ts +7 -5241
- package/dist/schemas/contract.schema.d.ts.map +1 -1
- package/dist/schemas/dispute-evidence.schema.d.ts +8 -3747
- package/dist/schemas/dispute-evidence.schema.d.ts.map +1 -1
- package/dist/schemas/dispute.schema.d.ts +8 -4926
- package/dist/schemas/dispute.schema.d.ts.map +1 -1
- package/dist/schemas/donation.schema.d.ts +8 -3552
- package/dist/schemas/donation.schema.d.ts.map +1 -1
- package/dist/schemas/escrow.schema.d.ts +8 -4279
- package/dist/schemas/escrow.schema.d.ts.map +1 -1
- package/dist/schemas/flag.schema.d.ts +8 -4332
- package/dist/schemas/flag.schema.d.ts.map +1 -1
- package/dist/schemas/interest.schema.d.ts +7 -3811
- package/dist/schemas/interest.schema.d.ts.map +1 -1
- package/dist/schemas/match.schema.d.ts +7 -3941
- package/dist/schemas/match.schema.d.ts.map +1 -1
- package/dist/schemas/message.schema.d.ts +7 -4071
- package/dist/schemas/message.schema.d.ts.map +1 -1
- package/dist/schemas/milestone.schema.d.ts +8 -4267
- package/dist/schemas/milestone.schema.d.ts.map +1 -1
- package/dist/schemas/notification.schema.d.ts +8 -4595
- package/dist/schemas/notification.schema.d.ts.map +1 -1
- package/dist/schemas/profile.schema.d.ts +16 -9241
- package/dist/schemas/profile.schema.d.ts.map +1 -1
- package/dist/schemas/profit-share-agreement.schema.d.ts +7 -3746
- package/dist/schemas/profit-share-agreement.schema.d.ts.map +1 -1
- package/dist/schemas/profit-share.schema.d.ts +7 -4006
- package/dist/schemas/profit-share.schema.d.ts.map +1 -1
- package/dist/schemas/promo-code.schema.d.ts +7 -3876
- package/dist/schemas/promo-code.schema.d.ts.map +1 -1
- package/dist/schemas/proposal.schema.d.ts +8 -5139
- package/dist/schemas/proposal.schema.d.ts.map +1 -1
- package/dist/schemas/purchase.schema.d.ts +8 -3682
- package/dist/schemas/purchase.schema.d.ts.map +1 -1
- package/dist/schemas/requirement-post.schema.d.ts +8 -6272
- package/dist/schemas/requirement-post.schema.d.ts.map +1 -1
- package/dist/schemas/review.schema.d.ts +8 -4462
- package/dist/schemas/review.schema.d.ts.map +1 -1
- package/dist/schemas/service-listing.schema.d.ts +8 -5109
- package/dist/schemas/service-listing.schema.d.ts.map +1 -1
- package/dist/schemas/subscription.schema.d.ts +8 -3942
- package/dist/schemas/subscription.schema.d.ts.map +1 -1
- package/dist/schemas/tmc-application.schema.d.ts +8 -4316
- package/dist/schemas/tmc-application.schema.d.ts.map +1 -1
- package/dist/schemas/tmc-membership.schema.d.ts +8 -3942
- package/dist/schemas/tmc-membership.schema.d.ts.map +1 -1
- package/dist/schemas/trust-badge.schema.d.ts +7 -3876
- package/dist/schemas/trust-badge.schema.d.ts.map +1 -1
- package/dist/schemas/verification.schema.d.ts +8 -4564
- package/dist/schemas/verification.schema.d.ts.map +1 -1
- package/dist/schemas/webhook-event.schema.d.ts +7 -3489
- package/dist/schemas/webhook-event.schema.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/backend/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { getConfig, getConfigValue, initConfig, isConfigInitialized, type ServiceConfig } from './config.js';
|
|
2
|
-
export { createLogger, logger, type LogEntry, type
|
|
2
|
+
export { createLogger, logger, type LogEntry, type Logger, type LogLevel } from './logger.js';
|
|
3
3
|
export { connectDatabase, disconnectDatabase, getDatabaseConnection, getMongoose, isDatabaseConnected, setMongoose, } from './database.js';
|
|
4
4
|
export { emitNotification, getFirebaseAdmin, getFirebaseAuth, getFirebaseMessaging, getFirebaseStorage, getFirestore, getRealtimeDatabase, initFirebase, isFirebaseInitialized, sendMulticastNotification, sendPushNotification, setFirebaseAdmin, type PushNotificationData, } from './firebase.js';
|
|
5
5
|
export { postWorkerRequest, scheduleWorkerRequest, scheduleWorkerRequestAt, setCloudTasksClient, type WorkerRequestOptions, type WorkerRequestPayload, } from './worker-queue.js';
|
|
6
6
|
export { closeRedisConnections, createRedisClients, getRedisClient, getRedisPubClient, getRedisSubClient, redisDel, redisGet, redisPublish, redisSet, redisSubscribe, setRedisClients, } from './redis.js';
|
|
7
7
|
export { emitChatMessage, emitNewMatch, emitReadReceipt, emitTypingIndicator, getSocketServer, hasSocketServer, ioEmitToAccount, ioEmitToChat, ioEmitToMatch, ioEmitToUser, setSocketServer, subscribeToSocketEvents, type ChatMessagePayload, type NewMatchPayload, } from './socket.js';
|
|
8
|
+
export { clearServiceTokenCache, getServiceToken, setGoogleAuth, validateServiceRequest, verifyServiceToken, } from './service-auth.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7G,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,QAAQ,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7G,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG9F,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,WAAW,GACZ,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,oBAAoB,GAC1B,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,eAAe,EACf,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC"}
|
package/dist/backend/index.js
CHANGED
|
@@ -16,4 +16,6 @@ export { postWorkerRequest, scheduleWorkerRequest, scheduleWorkerRequestAt, setC
|
|
|
16
16
|
export { closeRedisConnections, createRedisClients, getRedisClient, getRedisPubClient, getRedisSubClient, redisDel, redisGet, redisPublish, redisSet, redisSubscribe, setRedisClients, } from './redis.js';
|
|
17
17
|
// Socket.IO
|
|
18
18
|
export { emitChatMessage, emitNewMatch, emitReadReceipt, emitTypingIndicator, getSocketServer, hasSocketServer, ioEmitToAccount, ioEmitToChat, ioEmitToMatch, ioEmitToUser, setSocketServer, subscribeToSocketEvents, } from './socket.js';
|
|
19
|
+
// Service-to-Service Authentication (Google OAuth2)
|
|
20
|
+
export { clearServiceTokenCache, getServiceToken, setGoogleAuth, validateServiceRequest, verifyServiceToken, } from './service-auth.js';
|
|
19
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,oCAAoC;AACpC,gDAAgD;AAChD,+CAA+C;AAE/C,gBAAgB;AAChB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAsB,MAAM,aAAa,CAAC;AAE7G,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,EAA6C,MAAM,aAAa,CAAC;AAE9F,WAAW;AACX,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,WAAW;AACX,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,GAEjB,MAAM,eAAe,CAAC;AAEvB,6BAA6B;AAC7B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAE3B,QAAQ;AACR,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,YAAY;AACZ,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,eAAe,EACf,uBAAuB,GAGxB,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,oCAAoC;AACpC,gDAAgD;AAChD,+CAA+C;AAE/C,gBAAgB;AAChB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,mBAAmB,EAAsB,MAAM,aAAa,CAAC;AAE7G,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,EAA6C,MAAM,aAAa,CAAC;AAE9F,WAAW;AACX,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,WAAW;AACX,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,GAEjB,MAAM,eAAe,CAAC;AAEvB,6BAA6B;AAC7B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAE3B,QAAQ;AACR,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,YAAY;AACZ,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,eAAe,EACf,uBAAuB,GAGxB,MAAM,aAAa,CAAC;AAErB,oDAAoD;AACpD,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set the google-auth-library module instance
|
|
3
|
+
* This should be called before using service auth functions
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* import * as googleAuth from 'google-auth-library';
|
|
7
|
+
* setGoogleAuth(googleAuth);
|
|
8
|
+
*/
|
|
9
|
+
export declare function setGoogleAuth(googleAuth: any): void;
|
|
10
|
+
/**
|
|
11
|
+
* Get a Google OAuth2 ID token for service-to-service authentication
|
|
12
|
+
* Uses Application Default Credentials (works on Google Cloud and locally with GOOGLE_APPLICATION_CREDENTIALS)
|
|
13
|
+
*
|
|
14
|
+
* @param targetAudience - The audience (typically the receiving service URL)
|
|
15
|
+
* @returns The ID token string
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const token = await getServiceToken('https://my-service-abc123.run.app');
|
|
19
|
+
* fetch(url, { headers: { Authorization: `Bearer ${token}` } });
|
|
20
|
+
*/
|
|
21
|
+
export declare function getServiceToken(targetAudience: string): Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Verify a Google OAuth2 ID token from another service
|
|
24
|
+
* Used by the receiving service to validate incoming service-to-service calls
|
|
25
|
+
*
|
|
26
|
+
* @param token - The ID token to verify
|
|
27
|
+
* @param expectedAudience - The expected audience (this service's URL)
|
|
28
|
+
* @returns The decoded token payload if valid
|
|
29
|
+
*/
|
|
30
|
+
export declare function verifyServiceToken(token: string, expectedAudience: string): Promise<{
|
|
31
|
+
iss: string;
|
|
32
|
+
sub: string;
|
|
33
|
+
aud: string;
|
|
34
|
+
exp: number;
|
|
35
|
+
iat: number;
|
|
36
|
+
email?: string;
|
|
37
|
+
email_verified?: boolean;
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Clear the token cache (useful for testing)
|
|
41
|
+
*/
|
|
42
|
+
export declare function clearServiceTokenCache(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Check if a request has valid service-to-service authentication
|
|
45
|
+
* Returns the verified payload or null if not a service request
|
|
46
|
+
*
|
|
47
|
+
* @param authHeader - The Authorization header value
|
|
48
|
+
* @param expectedAudience - The expected audience
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateServiceRequest(authHeader: string | undefined, expectedAudience: string): Promise<{
|
|
51
|
+
isServiceRequest: boolean;
|
|
52
|
+
payload?: Awaited<ReturnType<typeof verifyServiceToken>>;
|
|
53
|
+
}>;
|
|
54
|
+
//# sourceMappingURL=service-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-auth.d.ts","sourceRoot":"","sources":["../../src/backend/service-auth.ts"],"names":[],"mappings":"AAiBA;;;;;;;GAOG;AAEH,wBAAgB,aAAa,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI,CAEnD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8C7E;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC;IACT,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC,CA+BD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC;IAAE,gBAAgB,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAA;CAAE,CAAC,CAqBlG"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// ============================================
|
|
2
|
+
// Service-to-Service Authentication
|
|
3
|
+
// Google OAuth2 ID Token generation for internal service calls
|
|
4
|
+
// ============================================
|
|
5
|
+
import { logger } from './logger.js';
|
|
6
|
+
// Store google-auth-library instance to avoid hard dependency
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
+
let googleAuthInstance = null;
|
|
9
|
+
// Cache for ID tokens (keyed by audience)
|
|
10
|
+
const tokenCache = new Map();
|
|
11
|
+
// Buffer time before expiry to refresh token (5 minutes)
|
|
12
|
+
const TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1000;
|
|
13
|
+
/**
|
|
14
|
+
* Set the google-auth-library module instance
|
|
15
|
+
* This should be called before using service auth functions
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* import * as googleAuth from 'google-auth-library';
|
|
19
|
+
* setGoogleAuth(googleAuth);
|
|
20
|
+
*/
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
export function setGoogleAuth(googleAuth) {
|
|
23
|
+
googleAuthInstance = googleAuth;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get a Google OAuth2 ID token for service-to-service authentication
|
|
27
|
+
* Uses Application Default Credentials (works on Google Cloud and locally with GOOGLE_APPLICATION_CREDENTIALS)
|
|
28
|
+
*
|
|
29
|
+
* @param targetAudience - The audience (typically the receiving service URL)
|
|
30
|
+
* @returns The ID token string
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const token = await getServiceToken('https://my-service-abc123.run.app');
|
|
34
|
+
* fetch(url, { headers: { Authorization: `Bearer ${token}` } });
|
|
35
|
+
*/
|
|
36
|
+
export async function getServiceToken(targetAudience) {
|
|
37
|
+
if (!googleAuthInstance) {
|
|
38
|
+
throw new Error('Google Auth not initialized. Call setGoogleAuth() first.');
|
|
39
|
+
}
|
|
40
|
+
// Check cache
|
|
41
|
+
const cached = tokenCache.get(targetAudience);
|
|
42
|
+
if (cached && cached.expiresAt > Date.now() + TOKEN_REFRESH_BUFFER_MS) {
|
|
43
|
+
return cached.token;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
// Create an IAM-based ID token client
|
|
47
|
+
const auth = new googleAuthInstance.GoogleAuth();
|
|
48
|
+
const client = await auth.getIdTokenClient(targetAudience);
|
|
49
|
+
// Get the ID token
|
|
50
|
+
const tokenResponse = await client.getRequestHeaders();
|
|
51
|
+
const authHeader = tokenResponse.Authorization;
|
|
52
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
53
|
+
throw new Error('Invalid token response from Google Auth');
|
|
54
|
+
}
|
|
55
|
+
const token = authHeader.replace('Bearer ', '');
|
|
56
|
+
// Parse token to get expiry (JWT format: header.payload.signature)
|
|
57
|
+
const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
58
|
+
const expiresAt = (payload.exp || 0) * 1000; // Convert to milliseconds
|
|
59
|
+
// Cache the token
|
|
60
|
+
tokenCache.set(targetAudience, { token, expiresAt });
|
|
61
|
+
logger.debug('Service token generated', {
|
|
62
|
+
audience: targetAudience,
|
|
63
|
+
expiresIn: Math.round((expiresAt - Date.now()) / 1000) + 's',
|
|
64
|
+
});
|
|
65
|
+
return token;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
logger.error('Failed to get service token', {
|
|
69
|
+
audience: targetAudience,
|
|
70
|
+
error: error instanceof Error ? error.message : String(error),
|
|
71
|
+
});
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Verify a Google OAuth2 ID token from another service
|
|
77
|
+
* Used by the receiving service to validate incoming service-to-service calls
|
|
78
|
+
*
|
|
79
|
+
* @param token - The ID token to verify
|
|
80
|
+
* @param expectedAudience - The expected audience (this service's URL)
|
|
81
|
+
* @returns The decoded token payload if valid
|
|
82
|
+
*/
|
|
83
|
+
export async function verifyServiceToken(token, expectedAudience) {
|
|
84
|
+
if (!googleAuthInstance) {
|
|
85
|
+
throw new Error('Google Auth not initialized. Call setGoogleAuth() first.');
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const client = new googleAuthInstance.OAuth2Client();
|
|
89
|
+
const ticket = await client.verifyIdToken({
|
|
90
|
+
idToken: token,
|
|
91
|
+
audience: expectedAudience,
|
|
92
|
+
});
|
|
93
|
+
const payload = ticket.getPayload();
|
|
94
|
+
if (!payload) {
|
|
95
|
+
throw new Error('Token payload is empty');
|
|
96
|
+
}
|
|
97
|
+
logger.debug('Service token verified', {
|
|
98
|
+
email: payload.email,
|
|
99
|
+
audience: payload.aud,
|
|
100
|
+
});
|
|
101
|
+
return payload;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
logger.error('Failed to verify service token', {
|
|
105
|
+
error: error instanceof Error ? error.message : String(error),
|
|
106
|
+
});
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Clear the token cache (useful for testing)
|
|
112
|
+
*/
|
|
113
|
+
export function clearServiceTokenCache() {
|
|
114
|
+
tokenCache.clear();
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Check if a request has valid service-to-service authentication
|
|
118
|
+
* Returns the verified payload or null if not a service request
|
|
119
|
+
*
|
|
120
|
+
* @param authHeader - The Authorization header value
|
|
121
|
+
* @param expectedAudience - The expected audience
|
|
122
|
+
*/
|
|
123
|
+
export async function validateServiceRequest(authHeader, expectedAudience) {
|
|
124
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
125
|
+
return { isServiceRequest: false };
|
|
126
|
+
}
|
|
127
|
+
const token = authHeader.replace('Bearer ', '');
|
|
128
|
+
try {
|
|
129
|
+
const payload = await verifyServiceToken(token, expectedAudience);
|
|
130
|
+
// Service tokens have specific characteristics
|
|
131
|
+
// They come from service accounts (email ends with .iam.gserviceaccount.com)
|
|
132
|
+
if (payload.email && payload.email.endsWith('.iam.gserviceaccount.com')) {
|
|
133
|
+
return { isServiceRequest: true, payload };
|
|
134
|
+
}
|
|
135
|
+
return { isServiceRequest: false };
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// If verification fails, it's not a valid service request
|
|
139
|
+
return { isServiceRequest: false };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=service-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-auth.js","sourceRoot":"","sources":["../../src/backend/service-auth.ts"],"names":[],"mappings":"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"}
|