@easecation/iam-client 1.0.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/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @easecation/iam-client
2
+
3
+ IAM V2 client library for EaseCation services. Provides an API wrapper and an Express middleware for validating RS256 access tokens against IAM.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @easecation/iam-client
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```ts
14
+ import { IamClient } from '@easecation/iam-client';
15
+
16
+ const client = new IamClient({
17
+ iamBaseUrl: 'http://localhost:8401',
18
+ clientId: '10007',
19
+ clientSecret: 'YOUR_CLIENT_SECRET',
20
+ });
21
+
22
+ // Exchange OAuth code for access + refresh tokens
23
+ const tokens = await client.exchangeOAuthCode(code, redirectUri);
24
+
25
+ // Verify access token and fetch permissions
26
+ const verify = await client.verifyToken(tokens.access_token);
27
+ ```
28
+
29
+ ## Express Middleware
30
+
31
+ ```ts
32
+ import express from 'express';
33
+ import { IamClient, createIamAuthMiddleware } from '@easecation/iam-client';
34
+
35
+ const client = new IamClient({
36
+ iamBaseUrl: 'http://localhost:8401',
37
+ clientId: '10007',
38
+ clientSecret: 'YOUR_CLIENT_SECRET',
39
+ });
40
+
41
+ const iamAuth = createIamAuthMiddleware(client);
42
+
43
+ const router = express.Router();
44
+ router.get('/profile', iamAuth(), (req, res) => {
45
+ const iamReq = req as any;
46
+ res.json({ uid: iamReq.iamUid, permissions: iamReq.iamPermissions });
47
+ });
48
+
49
+ router.post('/admin', iamAuth(['admin.write']), handler);
50
+ ```
51
+
52
+ ## API Highlights
53
+
54
+ - `getAppSessionToken()`
55
+ - `exchangeOAuthCode(code, redirectUri)`
56
+ - `verifyToken(accessToken)`
57
+ - `refreshToken(refreshToken)`
58
+ - `revokeToken(refreshToken)`
59
+ - `getUserProfile(accessToken)`
60
+ - `getUserPermissions(userId, targetApplicationId?)`
61
+ - `getJwks()`
62
+
63
+ ## Notes
64
+
65
+ - App session authentication uses the `X-App-Session-Token` header.
66
+ - Verify results are cached locally with a TTL that never exceeds the access token expiration.
@@ -0,0 +1,69 @@
1
+ /**
2
+ * IamClient — IAM V2 API wrapper.
3
+ *
4
+ * Usage:
5
+ * const client = new IamClient({
6
+ * iamBaseUrl: 'http://authapi.easecation.net',
7
+ * clientId: '10007',
8
+ * clientSecret: 'secret',
9
+ * });
10
+ *
11
+ * // Exchange OAuth code during login callback
12
+ * const tokens = await client.exchangeOAuthCode(code, redirectUri);
13
+ *
14
+ * // Verify a token on each request
15
+ * const result = await client.verifyToken(accessToken);
16
+ */
17
+ import { IamClientConfig, OAuthTokenData, VerifyTokenData, RefreshTokenData, JwksData, UserProfileData } from './types';
18
+ export declare class IamClient {
19
+ private readonly config;
20
+ private readonly http;
21
+ /** Cached app session token */
22
+ private cachedAppToken;
23
+ /** Permission/verify cache keyed by access_token */
24
+ private verifyCache;
25
+ constructor(config: IamClientConfig);
26
+ /**
27
+ * Get (or return cached) the App Session Token.
28
+ * This token is used to authenticate subsequent API calls to IAM.
29
+ */
30
+ getAppSessionToken(): Promise<string>;
31
+ /** Invalidate the cached app session token (force re-auth on next call). */
32
+ invalidateAppToken(): void;
33
+ /**
34
+ * Exchange an OAuth2 authorization code for a V2 token pair.
35
+ * Returns { access_token, expires_in, refresh_token, refresh_token_expires_in }.
36
+ */
37
+ exchangeOAuthCode(code: string, redirectUri: string): Promise<OAuthTokenData>;
38
+ /**
39
+ * Verify an Access Token and retrieve the associated permissions.
40
+ * Results are cached for `permissionCacheTtlMs` to avoid hammering IAM.
41
+ */
42
+ verifyToken(accessToken: string): Promise<VerifyTokenData>;
43
+ /** Remove a token from the local verify cache (e.g. after logout). */
44
+ evictFromVerifyCache(accessToken: string): void;
45
+ /**
46
+ * Exchange a Refresh Token for a new Access Token.
47
+ */
48
+ refreshToken(refreshToken: string): Promise<RefreshTokenData>;
49
+ /**
50
+ * Revoke a session by its Refresh Token (logout).
51
+ */
52
+ revokeToken(refreshToken: string): Promise<boolean>;
53
+ /**
54
+ * Fetch the JWKS (JSON Web Key Set) from IAM.
55
+ * Used for local RS256 token verification without a network call.
56
+ */
57
+ getJwks(): Promise<JwksData>;
58
+ /**
59
+ * Get profile of the user who owns the given Access Token.
60
+ */
61
+ getUserProfile(accessToken: string): Promise<UserProfileData>;
62
+ /**
63
+ * Get permissions for a specific user+application.
64
+ * @param userId IAM uid
65
+ * @param targetApplicationId Defaults to the calling application.
66
+ */
67
+ getUserPermissions(userId: number, targetApplicationId?: number): Promise<string[]>;
68
+ }
69
+ //# sourceMappingURL=IamClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IamClient.d.ts","sourceRoot":"","sources":["../src/IamClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,eAAe,EAGf,cAAc,EACd,eAAe,EACf,gBAAgB,EAEhB,QAAQ,EACR,eAAe,EAEhB,MAAM,SAAS,CAAC;AAYjB,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IAErC,+BAA+B;IAC/B,OAAO,CAAC,cAAc,CAA+B;IAErD,oDAAoD;IACpD,OAAO,CAAC,WAAW,CAAyC;gBAEhD,MAAM,EAAE,eAAe;IAiBnC;;;OAGG;IACG,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IA2B3C,4EAA4E;IAC5E,kBAAkB,IAAI,IAAI;IAM1B;;;OAGG;IACG,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAmBnF;;;OAGG;IACG,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAoChE,sEAAsE;IACtE,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAM/C;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmBnE;;OAEG;IACG,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAezD;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;IAOlC;;OAEG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAmBnE;;;;OAIG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAqB1F"}
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ /**
3
+ * IamClient — IAM V2 API wrapper.
4
+ *
5
+ * Usage:
6
+ * const client = new IamClient({
7
+ * iamBaseUrl: 'http://authapi.easecation.net',
8
+ * clientId: '10007',
9
+ * clientSecret: 'secret',
10
+ * });
11
+ *
12
+ * // Exchange OAuth code during login callback
13
+ * const tokens = await client.exchangeOAuthCode(code, redirectUri);
14
+ *
15
+ * // Verify a token on each request
16
+ * const result = await client.verifyToken(accessToken);
17
+ */
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.IamClient = void 0;
23
+ const axios_1 = __importDefault(require("axios"));
24
+ class IamClient {
25
+ constructor(config) {
26
+ /** Cached app session token */
27
+ this.cachedAppToken = null;
28
+ /** Permission/verify cache keyed by access_token */
29
+ this.verifyCache = new Map();
30
+ this.config = {
31
+ appTokenCacheTtlMs: 55 * 60 * 1000, // 55 minutes
32
+ permissionCacheTtlMs: 5 * 60 * 1000, // 5 minutes
33
+ timeoutMs: 5000,
34
+ ...config,
35
+ };
36
+ this.http = axios_1.default.create({
37
+ baseURL: this.config.iamBaseUrl,
38
+ timeout: this.config.timeoutMs,
39
+ headers: { 'Content-Type': 'application/json' },
40
+ });
41
+ }
42
+ // ── App Session Token ────────────────────────────────────────────────────────
43
+ /**
44
+ * Get (or return cached) the App Session Token.
45
+ * This token is used to authenticate subsequent API calls to IAM.
46
+ */
47
+ async getAppSessionToken() {
48
+ const now = Date.now();
49
+ if (this.cachedAppToken && now < this.cachedAppToken.expiresAt) {
50
+ return this.cachedAppToken.token;
51
+ }
52
+ const response = await this.http.post('/api/open/v2/token', {
53
+ client_id: this.config.clientId,
54
+ client_secret: this.config.clientSecret,
55
+ });
56
+ const data = response.data;
57
+ if (!data.success || !data.data?.applicationSessionToken) {
58
+ throw new Error(`IAM: Failed to get app token: ${data.message || data.code}`);
59
+ }
60
+ this.cachedAppToken = {
61
+ token: data.data.applicationSessionToken,
62
+ expiresAt: now + this.config.appTokenCacheTtlMs,
63
+ };
64
+ return this.cachedAppToken.token;
65
+ }
66
+ /** Invalidate the cached app session token (force re-auth on next call). */
67
+ invalidateAppToken() {
68
+ this.cachedAppToken = null;
69
+ }
70
+ // ── OAuth2 Code Exchange ─────────────────────────────────────────────────────
71
+ /**
72
+ * Exchange an OAuth2 authorization code for a V2 token pair.
73
+ * Returns { access_token, expires_in, refresh_token, refresh_token_expires_in }.
74
+ */
75
+ async exchangeOAuthCode(code, redirectUri) {
76
+ const appToken = await this.getAppSessionToken();
77
+ const response = await this.http.post('/api/open/v2/oauth/token', { code, redirect_uri: redirectUri }, { headers: { 'X-App-Session-Token': appToken } });
78
+ const data = response.data;
79
+ if (!data.success || !data.data) {
80
+ throw new Error(`IAM: OAuth code exchange failed: ${data.message || data.code}`);
81
+ }
82
+ return data.data;
83
+ }
84
+ // ── Token Verify ─────────────────────────────────────────────────────────────
85
+ /**
86
+ * Verify an Access Token and retrieve the associated permissions.
87
+ * Results are cached for `permissionCacheTtlMs` to avoid hammering IAM.
88
+ */
89
+ async verifyToken(accessToken) {
90
+ const now = Date.now();
91
+ const cached = this.verifyCache.get(accessToken);
92
+ if (cached && now < cached.expiresAt) {
93
+ return cached.result;
94
+ }
95
+ const appToken = await this.getAppSessionToken();
96
+ const response = await this.http.post('/api/open/v2/verify', { access_token: accessToken }, { headers: { 'X-App-Session-Token': appToken } });
97
+ const data = response.data;
98
+ if (!data.success || !data.data) {
99
+ // Evict any stale cache entry so the next request also hits IAM
100
+ // (covers the case where IAM revoked the session between cache fills)
101
+ this.verifyCache.delete(accessToken);
102
+ throw new Error(`IAM: Token verification failed: ${data.message || data.code}`);
103
+ }
104
+ // Cache should never outlive the access token expiration.
105
+ const expMs = data.data.exp * 1000;
106
+ const cacheExpiresAt = Math.min(now + this.config.permissionCacheTtlMs, expMs - 1000);
107
+ if (cacheExpiresAt > now) {
108
+ this.verifyCache.set(accessToken, {
109
+ result: data.data,
110
+ expiresAt: cacheExpiresAt,
111
+ });
112
+ }
113
+ return data.data;
114
+ }
115
+ /** Remove a token from the local verify cache (e.g. after logout). */
116
+ evictFromVerifyCache(accessToken) {
117
+ this.verifyCache.delete(accessToken);
118
+ }
119
+ // ── Token Refresh ─────────────────────────────────────────────────────────────
120
+ /**
121
+ * Exchange a Refresh Token for a new Access Token.
122
+ */
123
+ async refreshToken(refreshToken) {
124
+ const appToken = await this.getAppSessionToken();
125
+ const response = await this.http.post('/api/open/v2/refresh', { refresh_token: refreshToken }, { headers: { 'X-App-Session-Token': appToken } });
126
+ const data = response.data;
127
+ if (!data.success || !data.data) {
128
+ throw new Error(`IAM: Token refresh failed: ${data.message || data.code}`);
129
+ }
130
+ return data.data;
131
+ }
132
+ // ── Session Revoke ────────────────────────────────────────────────────────────
133
+ /**
134
+ * Revoke a session by its Refresh Token (logout).
135
+ */
136
+ async revokeToken(refreshToken) {
137
+ const appToken = await this.getAppSessionToken();
138
+ const response = await this.http.post('/api/open/v2/revoke', { refresh_token: refreshToken }, { headers: { 'X-App-Session-Token': appToken } });
139
+ const data = response.data;
140
+ return !!(data.success && data.data?.revoked);
141
+ }
142
+ // ── JWKS ──────────────────────────────────────────────────────────────────────
143
+ /**
144
+ * Fetch the JWKS (JSON Web Key Set) from IAM.
145
+ * Used for local RS256 token verification without a network call.
146
+ */
147
+ async getJwks() {
148
+ const response = await this.http.get('/api/open/v2/jwks');
149
+ return response.data;
150
+ }
151
+ // ── User Profile ──────────────────────────────────────────────────────────────
152
+ /**
153
+ * Get profile of the user who owns the given Access Token.
154
+ */
155
+ async getUserProfile(accessToken) {
156
+ const appToken = await this.getAppSessionToken();
157
+ const response = await this.http.post('/api/open/v2/user/profile', { access_token: accessToken }, { headers: { 'X-App-Session-Token': appToken } });
158
+ const data = response.data;
159
+ if (!data.success || !data.data) {
160
+ throw new Error(`IAM: getUserProfile failed: ${data.message || data.code}`);
161
+ }
162
+ return data.data;
163
+ }
164
+ // ── User Permissions ──────────────────────────────────────────────────────────
165
+ /**
166
+ * Get permissions for a specific user+application.
167
+ * @param userId IAM uid
168
+ * @param targetApplicationId Defaults to the calling application.
169
+ */
170
+ async getUserPermissions(userId, targetApplicationId) {
171
+ const appToken = await this.getAppSessionToken();
172
+ const body = { user_id: userId };
173
+ if (targetApplicationId !== undefined) {
174
+ body.target_application_id = targetApplicationId;
175
+ }
176
+ const response = await this.http.post('/api/open/v2/user/permissions', body, { headers: { 'X-App-Session-Token': appToken } });
177
+ const data = response.data;
178
+ if (!data.success || !data.data) {
179
+ throw new Error(`IAM: getUserPermissions failed: ${data.message || data.code}`);
180
+ }
181
+ return data.data.permissions;
182
+ }
183
+ }
184
+ exports.IamClient = IamClient;
185
+ //# sourceMappingURL=IamClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IamClient.js","sourceRoot":"","sources":["../src/IamClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { IamClient } from './IamClient';
2
+ export { createIamAuthMiddleware } from './middleware';
3
+ export type { IamRequest } from './middleware';
4
+ export type { IamClientConfig, IamApiResponse, AppTokenData, OAuthTokenData, VerifyTokenData, RefreshTokenData, RevokeTokenData, JwkData, JwksData, UserProfileData, UserPermissionsData, DecodedAccessToken, IamAuthRequest, } from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EACV,eAAe,EACf,cAAc,EACd,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,OAAO,EACP,QAAQ,EACR,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,GACf,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createIamAuthMiddleware = exports.IamClient = void 0;
4
+ var IamClient_1 = require("./IamClient");
5
+ Object.defineProperty(exports, "IamClient", { enumerable: true, get: function () { return IamClient_1.IamClient; } });
6
+ var middleware_1 = require("./middleware");
7
+ Object.defineProperty(exports, "createIamAuthMiddleware", { enumerable: true, get: function () { return middleware_1.createIamAuthMiddleware; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,2CAAuD;AAA9C,qHAAA,uBAAuB,OAAA"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Express middleware factory for IAM V2 authentication.
3
+ *
4
+ * Usage:
5
+ * import { createIamAuthMiddleware } from '@easecation/iam-client';
6
+ *
7
+ * const iamAuth = createIamAuthMiddleware(iamClient);
8
+ *
9
+ * // Protect a route (no permission requirements)
10
+ * router.get('/profile', iamAuth(), handler);
11
+ *
12
+ * // Protect a route and require specific permissions
13
+ * router.post('/admin', iamAuth(['admin.write']), handler);
14
+ */
15
+ import type { Request, Response, NextFunction } from 'express';
16
+ import { IamClient } from './IamClient';
17
+ /** Express Request extended with IAM claims */
18
+ export interface IamRequest extends Request {
19
+ iamUid: number;
20
+ iamApplicationId: number;
21
+ iamPermissions: string[];
22
+ iamTokenExp: number;
23
+ }
24
+ type IamMiddlewareFn = (req: Request, res: Response, next: NextFunction) => Promise<void>;
25
+ /**
26
+ * Create an auth middleware factory bound to an IamClient instance.
27
+ *
28
+ * @param client Configured IamClient.
29
+ * @returns A function `iamAuth(requiredPermissions?)` that returns an Express middleware.
30
+ */
31
+ export declare function createIamAuthMiddleware(client: IamClient): (requiredPermissions?: string[]) => IamMiddlewareFn;
32
+ export {};
33
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,+CAA+C;AAC/C,MAAM,WAAW,UAAW,SAAQ,OAAO;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,eAAe,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1F;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,IAC/B,sBAAqB,MAAM,EAAO,KAAG,eAAe,CAwE7E"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ /**
3
+ * Express middleware factory for IAM V2 authentication.
4
+ *
5
+ * Usage:
6
+ * import { createIamAuthMiddleware } from '@easecation/iam-client';
7
+ *
8
+ * const iamAuth = createIamAuthMiddleware(iamClient);
9
+ *
10
+ * // Protect a route (no permission requirements)
11
+ * router.get('/profile', iamAuth(), handler);
12
+ *
13
+ * // Protect a route and require specific permissions
14
+ * router.post('/admin', iamAuth(['admin.write']), handler);
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.createIamAuthMiddleware = createIamAuthMiddleware;
18
+ /**
19
+ * Create an auth middleware factory bound to an IamClient instance.
20
+ *
21
+ * @param client Configured IamClient.
22
+ * @returns A function `iamAuth(requiredPermissions?)` that returns an Express middleware.
23
+ */
24
+ function createIamAuthMiddleware(client) {
25
+ return function iamAuth(requiredPermissions = []) {
26
+ return async (req, res, next) => {
27
+ const authHeader = req.headers['authorization'];
28
+ if (!authHeader) {
29
+ res.status(401).json({ success: false, message: 'Missing authorization header' });
30
+ return;
31
+ }
32
+ const parts = authHeader.split(' ');
33
+ if (parts.length !== 2 || parts[0] !== 'Bearer') {
34
+ res.status(401).json({ success: false, message: 'Invalid authorization format' });
35
+ return;
36
+ }
37
+ const accessToken = parts[1];
38
+ try {
39
+ const result = await client.verifyToken(accessToken);
40
+ if (!result.valid) {
41
+ res.status(401).json({ success: false, message: 'Invalid access token' });
42
+ return;
43
+ }
44
+ // Permission check
45
+ if (requiredPermissions.length > 0) {
46
+ const hasAll = requiredPermissions.every(p => result.permissions.includes(p));
47
+ if (!hasAll) {
48
+ res.status(403).json({ success: false, message: 'Insufficient permissions' });
49
+ return;
50
+ }
51
+ }
52
+ // Attach claims to request
53
+ const iamReq = req;
54
+ iamReq.iamUid = result.uid;
55
+ iamReq.iamApplicationId = result.application_id;
56
+ iamReq.iamPermissions = result.permissions;
57
+ iamReq.iamTokenExp = result.exp;
58
+ next();
59
+ }
60
+ catch (error) {
61
+ // Distinguish IAM-reported token errors from network / server errors.
62
+ // IamClient.verifyToken throws "IAM: Token verification failed: <CODE>"
63
+ // for token-level rejections. Network errors carry an error.code.
64
+ const msg = error?.message || '';
65
+ const isTokenError = msg.startsWith('IAM: Token verification failed:') ||
66
+ msg === 'IAM: Token verification failed: ERROR_V2_INVALID_TOKEN' ||
67
+ msg === 'IAM: Token verification failed: ERROR_V2_TOKEN_EXPIRED';
68
+ const isNetworkError = error?.code === 'ECONNREFUSED' ||
69
+ error?.code === 'ENOTFOUND' ||
70
+ error?.code === 'ETIMEDOUT' ||
71
+ (error?.response?.status != null && error.response.status >= 500);
72
+ if (isTokenError) {
73
+ res.status(401).json({ success: false, message: 'Invalid or expired access token' });
74
+ return;
75
+ }
76
+ if (isNetworkError) {
77
+ console.error('[IamClient] IAM unreachable:', error?.code || error?.message);
78
+ res.status(503).json({ success: false, message: 'Authentication service temporarily unavailable' });
79
+ return;
80
+ }
81
+ console.error('[IamClient] Auth middleware error:', error);
82
+ res.status(500).json({ success: false, message: 'Authentication service error' });
83
+ }
84
+ };
85
+ };
86
+ }
87
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Types for the @easecation/iam-client package.
3
+ */
4
+ export interface IamApiResponse<T = unknown> {
5
+ success: boolean;
6
+ data?: T;
7
+ message?: string;
8
+ code?: string;
9
+ }
10
+ export interface AppTokenData {
11
+ applicationSessionToken: string;
12
+ applicationId: number;
13
+ }
14
+ export interface OAuthTokenData {
15
+ access_token: string;
16
+ expires_in: number;
17
+ refresh_token: string;
18
+ refresh_token_expires_in: number;
19
+ token_type: 'Bearer';
20
+ }
21
+ export interface VerifyTokenData {
22
+ valid: boolean;
23
+ uid: number;
24
+ application_id: number;
25
+ permissions: string[];
26
+ exp: number;
27
+ }
28
+ export interface RefreshTokenData {
29
+ access_token: string;
30
+ expires_in: number;
31
+ token_type: 'Bearer';
32
+ }
33
+ export interface RevokeTokenData {
34
+ revoked: boolean;
35
+ }
36
+ export interface JwkData {
37
+ kty: 'RSA';
38
+ use: 'sig';
39
+ alg: 'RS256';
40
+ kid: string;
41
+ n: string;
42
+ e: string;
43
+ }
44
+ export interface JwksData {
45
+ keys: JwkData[];
46
+ }
47
+ export interface UserProfileData {
48
+ uid: number;
49
+ name: string;
50
+ email: string;
51
+ status: string;
52
+ }
53
+ export interface UserPermissionsData {
54
+ permissions: string[];
55
+ application_id: number;
56
+ user_id: number;
57
+ }
58
+ export interface IamClientConfig {
59
+ /** IAM backend URL, e.g. http://authapi.easecation.net */
60
+ iamBaseUrl: string;
61
+ /** Application client_id */
62
+ clientId: string;
63
+ /** Application client_secret */
64
+ clientSecret: string;
65
+ /**
66
+ * How long (ms) to cache the App Session Token.
67
+ * Defaults to 55 minutes (token lifetime is 1h by default in V1).
68
+ */
69
+ appTokenCacheTtlMs?: number;
70
+ /**
71
+ * How long (ms) to cache permission verification results locally.
72
+ * Defaults to 5 minutes.
73
+ */
74
+ permissionCacheTtlMs?: number;
75
+ /**
76
+ * Request timeout (ms). Defaults to 5000.
77
+ */
78
+ timeoutMs?: number;
79
+ }
80
+ export interface DecodedAccessToken {
81
+ uid: number;
82
+ app: number;
83
+ jti: string;
84
+ iat: number;
85
+ exp: number;
86
+ iss: string;
87
+ }
88
+ /** Augment Express Request with IAM claims */
89
+ export interface IamAuthRequest {
90
+ iamUid: number;
91
+ iamApplicationId: number;
92
+ iamPermissions: string[];
93
+ iamTokenExp: number;
94
+ }
95
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,uBAAuB,EAAE,MAAM,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,wBAAwB,EAAE,MAAM,CAAC;IACjC,UAAU,EAAE,QAAQ,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,QAAQ,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,WAAW,kBAAkB;IACjC,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,GAAG,EAAE,MAAM,CAAC;CACb;AAID,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Types for the @easecation/iam-client package.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@easecation/iam-client",
3
+ "version": "1.0.0",
4
+ "description": "IAM V2 client library for EaseCation services",
5
+ "license": "UNLICENSED",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "require": "./dist/index.js",
18
+ "types": "./dist/index.d.ts"
19
+ }
20
+ },
21
+ "keywords": [
22
+ "iam",
23
+ "oauth",
24
+ "jwt",
25
+ "rbac",
26
+ "easecation"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "dev": "tsc --watch"
31
+ },
32
+ "dependencies": {
33
+ "axios": "^1.6.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/express": "^4.17.21",
37
+ "@types/node": "^20.0.0",
38
+ "typescript": "^5.0.0"
39
+ },
40
+ "peerDependencies": {
41
+ "express": ">=4.0.0"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "express": {
45
+ "optional": true
46
+ }
47
+ }
48
+ }