@passflow/core 0.0.1 → 0.2.8
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/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3230 -639
- package/dist/index.mjs.map +1 -1
- package/dist/lib/api/app.d.ts +4 -1
- package/dist/lib/api/app.d.ts.map +1 -1
- package/dist/lib/api/auth.d.ts +6 -4
- package/dist/lib/api/auth.d.ts.map +1 -1
- package/dist/lib/api/axios-client.d.ts +26 -4
- package/dist/lib/api/axios-client.d.ts.map +1 -1
- package/dist/lib/api/index.d.ts +4 -3
- package/dist/lib/api/index.d.ts.map +1 -1
- package/dist/lib/api/invitation.d.ts +4 -1
- package/dist/lib/api/invitation.d.ts.map +1 -1
- package/dist/lib/api/model.d.ts +180 -11
- package/dist/lib/api/model.d.ts.map +1 -1
- package/dist/lib/api/setting.d.ts +4 -1
- package/dist/lib/api/setting.d.ts.map +1 -1
- package/dist/lib/api/tenant.d.ts +4 -1
- package/dist/lib/api/tenant.d.ts.map +1 -1
- package/dist/lib/api/two-factor.d.ts +75 -0
- package/dist/lib/api/two-factor.d.ts.map +1 -0
- package/dist/lib/api/user.d.ts +4 -1
- package/dist/lib/api/user.d.ts.map +1 -1
- package/dist/lib/constants/index.d.ts +25 -0
- package/dist/lib/constants/index.d.ts.map +1 -1
- package/dist/lib/device/index.d.ts +17 -0
- package/dist/lib/device/index.d.ts.map +1 -0
- package/dist/lib/index.d.ts +10 -3
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/m2m/client.d.ts +196 -0
- package/dist/lib/m2m/client.d.ts.map +1 -0
- package/dist/lib/m2m/errors.d.ts +107 -0
- package/dist/lib/m2m/errors.d.ts.map +1 -0
- package/dist/lib/m2m/index.d.ts +27 -0
- package/dist/lib/m2m/index.d.ts.map +1 -0
- package/dist/lib/m2m/types.d.ts +217 -0
- package/dist/lib/m2m/types.d.ts.map +1 -0
- package/dist/lib/passflow.d.ts +972 -11
- package/dist/lib/passflow.d.ts.map +1 -1
- package/dist/lib/services/auth-service.d.ts +29 -4
- package/dist/lib/services/auth-service.d.ts.map +1 -1
- package/dist/lib/services/index.d.ts +2 -1
- package/dist/lib/services/index.d.ts.map +1 -1
- package/dist/lib/services/invitation-service.d.ts +2 -2
- package/dist/lib/services/tenant-service.d.ts +2 -2
- package/dist/lib/services/token-cache-service.d.ts +14 -6
- package/dist/lib/services/token-cache-service.d.ts.map +1 -1
- package/dist/lib/services/two-factor-service.d.ts +120 -0
- package/dist/lib/services/two-factor-service.d.ts.map +1 -0
- package/dist/lib/services/user-service.d.ts +1 -1
- package/dist/lib/services/user-service.d.ts.map +1 -1
- package/dist/lib/storage/index.d.ts +96 -0
- package/dist/lib/storage/index.d.ts.map +1 -0
- package/dist/lib/store.d.ts +67 -1
- package/dist/lib/store.d.ts.map +1 -1
- package/dist/lib/token/delivery-manager.d.ts +121 -0
- package/dist/lib/token/delivery-manager.d.ts.map +1 -0
- package/dist/lib/{token-service → token}/index.d.ts +1 -1
- package/dist/lib/token/index.d.ts.map +1 -0
- package/dist/lib/token/membership.d.ts.map +1 -0
- package/dist/lib/{token-service → token}/service.d.ts +15 -3
- package/dist/lib/token/service.d.ts.map +1 -0
- package/dist/lib/token/token.d.ts +55 -0
- package/dist/lib/token/token.d.ts.map +1 -0
- package/dist/lib/types/index.d.ts +5 -3
- package/dist/lib/types/index.d.ts.map +1 -1
- package/dist/lib/utils/validation.d.ts +54 -0
- package/dist/lib/utils/validation.d.ts.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +13 -15
- package/dist/lib/device-service/index.d.ts +0 -7
- package/dist/lib/device-service/index.d.ts.map +0 -1
- package/dist/lib/storage-manager/index.d.ts +0 -37
- package/dist/lib/storage-manager/index.d.ts.map +0 -1
- package/dist/lib/token-service/index.d.ts.map +0 -1
- package/dist/lib/token-service/membership.d.ts.map +0 -1
- package/dist/lib/token-service/service.d.ts.map +0 -1
- package/dist/lib/token-service/token.d.ts +0 -34
- package/dist/lib/token-service/token.d.ts.map +0 -1
- package/dist/tests/storage-manager/fake-storage.d.ts +0 -7
- package/dist/tests/storage-manager/fake-storage.d.ts.map +0 -1
- package/dist/tests/storage-manager/storage-manager.test.d.ts +0 -2
- package/dist/tests/storage-manager/storage-manager.test.d.ts.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- /package/dist/lib/{token-service → token}/membership.d.ts +0 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M2M (Machine-to-Machine) Authentication Types
|
|
3
|
+
*
|
|
4
|
+
* OAuth 2.0 Client Credentials Grant implementation for server-to-server
|
|
5
|
+
* authentication without user involvement.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* M2M Client configuration options
|
|
9
|
+
*/
|
|
10
|
+
export type M2MClientConfig = {
|
|
11
|
+
/** Passflow server URL */
|
|
12
|
+
url: string;
|
|
13
|
+
/** M2M application client ID */
|
|
14
|
+
clientId: string;
|
|
15
|
+
/** M2M application client secret */
|
|
16
|
+
clientSecret: string;
|
|
17
|
+
/** Scopes to request (default: []) */
|
|
18
|
+
scopes?: string[];
|
|
19
|
+
/** Target audiences for the token */
|
|
20
|
+
audience?: string[];
|
|
21
|
+
/** Automatically refresh tokens before expiry (default: false) */
|
|
22
|
+
autoRefresh?: boolean;
|
|
23
|
+
/** Seconds before expiry to trigger refresh (default: 30) */
|
|
24
|
+
refreshThreshold?: number;
|
|
25
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
26
|
+
timeout?: number;
|
|
27
|
+
/** Number of retry attempts on failure (default: 3) */
|
|
28
|
+
retries?: number;
|
|
29
|
+
/** Delay between retries in milliseconds (default: 1000) */
|
|
30
|
+
retryDelay?: number;
|
|
31
|
+
/** Custom retry strategy */
|
|
32
|
+
retryStrategy?: RetryStrategy;
|
|
33
|
+
/** Custom token cache implementation */
|
|
34
|
+
cache?: M2MTokenCache;
|
|
35
|
+
/** Callback for token requests (for logging/metrics) */
|
|
36
|
+
onTokenRequest?: (request: M2MTokenRequestInfo) => void;
|
|
37
|
+
/** Callback for token responses (for logging/metrics) */
|
|
38
|
+
onTokenResponse?: (response: M2MTokenResponse) => void;
|
|
39
|
+
/** Callback for errors (for logging/metrics) */
|
|
40
|
+
onError?: (error: M2MErrorResponse) => void;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Token request options (can override defaults per-request)
|
|
44
|
+
*/
|
|
45
|
+
export type M2MTokenRequestOptions = {
|
|
46
|
+
/** Override default scopes for this request */
|
|
47
|
+
scopes?: string[];
|
|
48
|
+
/** Override default audience for this request */
|
|
49
|
+
audience?: string[];
|
|
50
|
+
/** Force a new token request, ignoring cache */
|
|
51
|
+
forceRefresh?: boolean;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Token request info (for logging callbacks)
|
|
55
|
+
*/
|
|
56
|
+
export type M2MTokenRequestInfo = {
|
|
57
|
+
/** Client ID being used */
|
|
58
|
+
clientId: string;
|
|
59
|
+
/** Scopes being requested */
|
|
60
|
+
scopes: string[];
|
|
61
|
+
/** Audiences being requested */
|
|
62
|
+
audience: string[];
|
|
63
|
+
/** Request timestamp */
|
|
64
|
+
timestamp: string;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* OAuth 2.0 token response from the authorization server
|
|
68
|
+
*/
|
|
69
|
+
export type M2MTokenResponse = {
|
|
70
|
+
/** The access token (JWT) */
|
|
71
|
+
access_token: string;
|
|
72
|
+
/** Token type (always "Bearer") */
|
|
73
|
+
token_type: 'Bearer';
|
|
74
|
+
/** Token lifetime in seconds */
|
|
75
|
+
expires_in: number;
|
|
76
|
+
/** Granted scopes (space-separated string) */
|
|
77
|
+
scope?: string;
|
|
78
|
+
/** Timestamp when token was issued (added by client) */
|
|
79
|
+
issued_at?: number;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* OAuth 2.0 error response from the authorization server
|
|
83
|
+
*/
|
|
84
|
+
export type M2MErrorResponse = {
|
|
85
|
+
/** OAuth 2.0 error code */
|
|
86
|
+
error: M2MErrorCode;
|
|
87
|
+
/** Human-readable error description */
|
|
88
|
+
error_description?: string;
|
|
89
|
+
/** URI with more information about the error */
|
|
90
|
+
error_uri?: string;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Parsed M2M JWT token claims
|
|
94
|
+
*/
|
|
95
|
+
export type M2MTokenClaims = {
|
|
96
|
+
/** Issuer (Passflow server URL) */
|
|
97
|
+
iss: string;
|
|
98
|
+
/** Subject (client_id) */
|
|
99
|
+
sub: string;
|
|
100
|
+
/** Audience (target APIs) */
|
|
101
|
+
aud: string | string[];
|
|
102
|
+
/** Issued at timestamp (Unix epoch seconds) */
|
|
103
|
+
iat: number;
|
|
104
|
+
/** Expiration timestamp (Unix epoch seconds) */
|
|
105
|
+
exp: number;
|
|
106
|
+
/** JWT ID (unique token identifier) */
|
|
107
|
+
jti?: string;
|
|
108
|
+
/** Token type ("m2m") */
|
|
109
|
+
type: 'm2m';
|
|
110
|
+
/** Client ID */
|
|
111
|
+
client_id: string;
|
|
112
|
+
/** Tenant ID (for tenant-scoped M2M apps) */
|
|
113
|
+
tenant_id?: string;
|
|
114
|
+
/** Granted scopes */
|
|
115
|
+
scopes: string[];
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* M2M error codes (OAuth 2.0 compliant)
|
|
119
|
+
*/
|
|
120
|
+
export type M2MErrorCode = 'invalid_request' | 'invalid_client' | 'invalid_grant' | 'invalid_scope' | 'unauthorized_client' | 'unsupported_grant_type' | 'rate_limit_exceeded' | 'server_error' | 'temporarily_unavailable';
|
|
121
|
+
/**
|
|
122
|
+
* M2M error code enum for convenience
|
|
123
|
+
*/
|
|
124
|
+
export declare const M2MErrorCodes: {
|
|
125
|
+
InvalidRequest: "invalid_request";
|
|
126
|
+
InvalidClient: "invalid_client";
|
|
127
|
+
InvalidGrant: "invalid_grant";
|
|
128
|
+
InvalidScope: "invalid_scope";
|
|
129
|
+
UnauthorizedClient: "unauthorized_client";
|
|
130
|
+
UnsupportedGrantType: "unsupported_grant_type";
|
|
131
|
+
RateLimitExceeded: "rate_limit_exceeded";
|
|
132
|
+
ServerError: "server_error";
|
|
133
|
+
TemporarilyUnavailable: "temporarily_unavailable";
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Custom token cache interface for external cache implementations
|
|
137
|
+
*/
|
|
138
|
+
export interface M2MTokenCache {
|
|
139
|
+
/**
|
|
140
|
+
* Get cached token by key
|
|
141
|
+
* @param key Cache key (typically clientId)
|
|
142
|
+
* @returns Cached token or null if not found/expired
|
|
143
|
+
*/
|
|
144
|
+
get(key: string): Promise<M2MTokenResponse | null>;
|
|
145
|
+
/**
|
|
146
|
+
* Cache a token with TTL
|
|
147
|
+
* @param key Cache key (typically clientId)
|
|
148
|
+
* @param token Token to cache
|
|
149
|
+
* @param ttl Time-to-live in seconds
|
|
150
|
+
*/
|
|
151
|
+
set(key: string, token: M2MTokenResponse, ttl: number): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* Delete cached token
|
|
154
|
+
* @param key Cache key (typically clientId)
|
|
155
|
+
*/
|
|
156
|
+
delete(key: string): Promise<void>;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Custom retry strategy interface
|
|
160
|
+
*/
|
|
161
|
+
export interface RetryStrategy {
|
|
162
|
+
/**
|
|
163
|
+
* Determine if the request should be retried
|
|
164
|
+
* @param error The error that occurred
|
|
165
|
+
* @param attempt Current attempt number (1-based)
|
|
166
|
+
* @returns true if request should be retried
|
|
167
|
+
*/
|
|
168
|
+
shouldRetry(error: {
|
|
169
|
+
code: M2MErrorCode;
|
|
170
|
+
status?: number;
|
|
171
|
+
}, attempt: number): boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Get delay before next retry
|
|
174
|
+
* @param attempt Current attempt number (1-based)
|
|
175
|
+
* @returns Delay in milliseconds
|
|
176
|
+
*/
|
|
177
|
+
getDelay(attempt: number): number;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Internal token request payload sent to the authorization server
|
|
181
|
+
*/
|
|
182
|
+
export type M2MTokenRequestPayload = {
|
|
183
|
+
grant_type: 'client_credentials';
|
|
184
|
+
client_id: string;
|
|
185
|
+
client_secret: string;
|
|
186
|
+
scope?: string;
|
|
187
|
+
audience?: string;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Rate limit information from response headers
|
|
191
|
+
*/
|
|
192
|
+
export type M2MRateLimitInfo = {
|
|
193
|
+
/** Maximum requests allowed in the window */
|
|
194
|
+
limit: number;
|
|
195
|
+
/** Remaining requests in the current window */
|
|
196
|
+
remaining: number;
|
|
197
|
+
/** Unix timestamp when the window resets */
|
|
198
|
+
reset: number;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Default configuration values
|
|
202
|
+
*/
|
|
203
|
+
export declare const M2M_DEFAULTS: {
|
|
204
|
+
/** Default token endpoint path */
|
|
205
|
+
readonly TOKEN_ENDPOINT: "/oauth2/token";
|
|
206
|
+
/** Default request timeout in milliseconds */
|
|
207
|
+
readonly TIMEOUT: 10000;
|
|
208
|
+
/** Default number of retry attempts */
|
|
209
|
+
readonly RETRIES: 3;
|
|
210
|
+
/** Default delay between retries in milliseconds */
|
|
211
|
+
readonly RETRY_DELAY: 1000;
|
|
212
|
+
/** Default refresh threshold in seconds */
|
|
213
|
+
readonly REFRESH_THRESHOLD: 30;
|
|
214
|
+
/** Content-Type for token requests */
|
|
215
|
+
readonly CONTENT_TYPE: "application/x-www-form-urlencoded";
|
|
216
|
+
};
|
|
217
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/m2m/types.ts"],"names":[],"mappings":"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"}
|