@armco/iam-client 0.1.1
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 +181 -0
- package/dist/client-CTKWBZ26.d.mts +185 -0
- package/dist/client-CTKWBZ26.d.ts +185 -0
- package/dist/index.d.mts +41 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +545 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +511 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.d.mts +61 -0
- package/dist/react.d.ts +61 -0
- package/dist/react.js +673 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +649 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# @armco/iam-client
|
|
2
|
+
|
|
3
|
+
Browser/SPA client for IAM - OIDC/OAuth2 authentication with PKCE.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @armco/iam-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Vanilla JavaScript/TypeScript
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { createIAMClient } from '@armco/iam-client';
|
|
17
|
+
|
|
18
|
+
const iam = createIAMClient({
|
|
19
|
+
issuer: 'http://localhost:5000',
|
|
20
|
+
clientId: 'my-app',
|
|
21
|
+
redirectUri: 'http://localhost:3000/callback',
|
|
22
|
+
scopes: ['openid', 'profile', 'email', 'offline_access'],
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Login
|
|
26
|
+
document.getElementById('login-btn').onclick = () => iam.login();
|
|
27
|
+
|
|
28
|
+
// Signup
|
|
29
|
+
document.getElementById('signup-btn').onclick = () => iam.signup();
|
|
30
|
+
|
|
31
|
+
// Handle callback (on /callback page)
|
|
32
|
+
const result = await iam.handleCallback();
|
|
33
|
+
if (result.success) {
|
|
34
|
+
console.log('Logged in:', result.user);
|
|
35
|
+
} else {
|
|
36
|
+
console.error('Login failed:', result.error);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Get current user
|
|
40
|
+
const user = iam.getUser();
|
|
41
|
+
|
|
42
|
+
// Get access token (auto-refreshes if needed)
|
|
43
|
+
const token = await iam.getAccessToken();
|
|
44
|
+
|
|
45
|
+
// Logout
|
|
46
|
+
await iam.logout();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### React
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { IAMProvider, useAuth } from '@armco/iam-client/react';
|
|
53
|
+
|
|
54
|
+
// Wrap your app
|
|
55
|
+
function App() {
|
|
56
|
+
return (
|
|
57
|
+
<IAMProvider
|
|
58
|
+
issuer="http://localhost:5000"
|
|
59
|
+
clientId="my-app"
|
|
60
|
+
redirectUri="http://localhost:3000/callback"
|
|
61
|
+
onLoginSuccess={(result) => {
|
|
62
|
+
console.log('Logged in:', result.user);
|
|
63
|
+
// Navigate to dashboard
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<Router>
|
|
67
|
+
<Routes>
|
|
68
|
+
<Route path="/" element={<Home />} />
|
|
69
|
+
<Route path="/callback" element={<Callback />} />
|
|
70
|
+
<Route path="/dashboard" element={<Dashboard />} />
|
|
71
|
+
</Routes>
|
|
72
|
+
</Router>
|
|
73
|
+
</StuffleIAMProvider>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Use the hook
|
|
78
|
+
function Home() {
|
|
79
|
+
const { isAuthenticated, isLoading, user, login, signup, logout } = useAuth();
|
|
80
|
+
|
|
81
|
+
if (isLoading) return <div>Loading...</div>;
|
|
82
|
+
|
|
83
|
+
if (!isAuthenticated) {
|
|
84
|
+
return (
|
|
85
|
+
<div>
|
|
86
|
+
<button onClick={() => login()}>Login</button>
|
|
87
|
+
<button onClick={() => signup()}>Sign Up</button>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<div>
|
|
94
|
+
<p>Welcome, {user?.name || user?.email}</p>
|
|
95
|
+
<button onClick={() => logout()}>Logout</button>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Callback page (auto-handled by provider)
|
|
101
|
+
function Callback() {
|
|
102
|
+
const { isLoading, error } = useAuth();
|
|
103
|
+
|
|
104
|
+
if (isLoading) return <div>Processing login...</div>;
|
|
105
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
106
|
+
|
|
107
|
+
return <Navigate to="/dashboard" />;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Configuration
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
interface StuffleIAMConfig {
|
|
115
|
+
/** IAM server base URL */
|
|
116
|
+
issuer: string;
|
|
117
|
+
/** OAuth2 client ID */
|
|
118
|
+
clientId: string;
|
|
119
|
+
/** Redirect URI after login */
|
|
120
|
+
redirectUri: string;
|
|
121
|
+
/** Requested scopes (default: openid profile email) */
|
|
122
|
+
scopes?: string[];
|
|
123
|
+
/** Post-logout redirect URI */
|
|
124
|
+
postLogoutRedirectUri?: string;
|
|
125
|
+
/** Enable PKCE (default: true) */
|
|
126
|
+
usePkce?: boolean;
|
|
127
|
+
/** Storage type (default: sessionStorage) */
|
|
128
|
+
storage?: 'localStorage' | 'sessionStorage' | 'memory';
|
|
129
|
+
/** Auto-refresh tokens (default: true) */
|
|
130
|
+
autoRefresh?: boolean;
|
|
131
|
+
/** Seconds before expiry to refresh (default: 60) */
|
|
132
|
+
refreshThreshold?: number;
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## React Hooks
|
|
137
|
+
|
|
138
|
+
| Hook | Description |
|
|
139
|
+
|------|-------------|
|
|
140
|
+
| `useAuth()` | Full auth context (user, login, logout, etc.) |
|
|
141
|
+
| `useUser()` | Current user object |
|
|
142
|
+
| `useIsAuthenticated()` | Boolean auth status |
|
|
143
|
+
| `useAccessToken()` | Function to get access token |
|
|
144
|
+
| `useHasRole(roles)` | Check if user has role(s) |
|
|
145
|
+
|
|
146
|
+
## Protected Routes (HOC)
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { withAuth } from '@armco/iam-client/react';
|
|
150
|
+
|
|
151
|
+
const ProtectedPage = withAuth(MyComponent, {
|
|
152
|
+
LoadingComponent: () => <div>Loading...</div>,
|
|
153
|
+
UnauthorizedComponent: () => <div>Please login</div>,
|
|
154
|
+
roles: ['admin'], // Optional: require specific roles
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## API Reference
|
|
159
|
+
|
|
160
|
+
### StuffleIAMClient Methods
|
|
161
|
+
|
|
162
|
+
| Method | Description |
|
|
163
|
+
|--------|-------------|
|
|
164
|
+
| `login(options?)` | Start login flow |
|
|
165
|
+
| `signup(options?)` | Start signup flow |
|
|
166
|
+
| `logout(options?)` | End session |
|
|
167
|
+
| `handleCallback(url?)` | Process OAuth callback |
|
|
168
|
+
| `getUser()` | Get current user from ID token |
|
|
169
|
+
| `getAccessToken()` | Get access token (refreshes if needed) |
|
|
170
|
+
| `isAuthenticated()` | Check if user is logged in |
|
|
171
|
+
| `refreshToken()` | Manually refresh tokens |
|
|
172
|
+
| `subscribe(listener)` | Subscribe to auth state changes |
|
|
173
|
+
|
|
174
|
+
## Development
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
cd packages/sdk-js
|
|
178
|
+
npm install
|
|
179
|
+
npm run build
|
|
180
|
+
npm run dev # Watch mode
|
|
181
|
+
```
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stuffle IAM SDK Types
|
|
3
|
+
*/
|
|
4
|
+
interface StuffleIAMConfig {
|
|
5
|
+
/** IAM server base URL (e.g., http://localhost:5000) */
|
|
6
|
+
issuer: string;
|
|
7
|
+
/** OAuth2 client ID */
|
|
8
|
+
clientId: string;
|
|
9
|
+
/** Redirect URI after login */
|
|
10
|
+
redirectUri: string;
|
|
11
|
+
/** Requested scopes (default: openid profile email) */
|
|
12
|
+
scopes?: string[];
|
|
13
|
+
/** Post-logout redirect URI */
|
|
14
|
+
postLogoutRedirectUri?: string;
|
|
15
|
+
/** Enable PKCE (default: true, recommended for SPAs) */
|
|
16
|
+
usePkce?: boolean;
|
|
17
|
+
/** Storage type for tokens (default: sessionStorage) */
|
|
18
|
+
storage?: 'localStorage' | 'sessionStorage' | 'memory';
|
|
19
|
+
/** Auto-refresh tokens before expiry (default: true) */
|
|
20
|
+
autoRefresh?: boolean;
|
|
21
|
+
/** Seconds before expiry to trigger refresh (default: 60) */
|
|
22
|
+
refreshThreshold?: number;
|
|
23
|
+
}
|
|
24
|
+
interface TokenResponse {
|
|
25
|
+
access_token: string;
|
|
26
|
+
token_type: string;
|
|
27
|
+
expires_in: number;
|
|
28
|
+
refresh_token?: string;
|
|
29
|
+
id_token?: string;
|
|
30
|
+
scope?: string;
|
|
31
|
+
}
|
|
32
|
+
interface User {
|
|
33
|
+
sub: string;
|
|
34
|
+
email?: string;
|
|
35
|
+
email_verified?: boolean;
|
|
36
|
+
name?: string;
|
|
37
|
+
given_name?: string;
|
|
38
|
+
family_name?: string;
|
|
39
|
+
picture?: string;
|
|
40
|
+
username?: string;
|
|
41
|
+
roles?: string[];
|
|
42
|
+
tenantId?: string;
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
interface AuthState {
|
|
46
|
+
isAuthenticated: boolean;
|
|
47
|
+
isLoading: boolean;
|
|
48
|
+
user: User | null;
|
|
49
|
+
accessToken: string | null;
|
|
50
|
+
idToken: string | null;
|
|
51
|
+
error: Error | null;
|
|
52
|
+
}
|
|
53
|
+
interface LoginOptions {
|
|
54
|
+
/** Additional scopes to request */
|
|
55
|
+
scopes?: string[];
|
|
56
|
+
/** State parameter (auto-generated if not provided) */
|
|
57
|
+
state?: string;
|
|
58
|
+
/** Nonce for ID token validation */
|
|
59
|
+
nonce?: string;
|
|
60
|
+
/** Redirect to signup instead of login */
|
|
61
|
+
signup?: boolean;
|
|
62
|
+
/** Prompt parameter (none, login, consent, select_account) */
|
|
63
|
+
prompt?: 'none' | 'login' | 'consent' | 'select_account';
|
|
64
|
+
/** Login hint (email or username) */
|
|
65
|
+
loginHint?: string;
|
|
66
|
+
}
|
|
67
|
+
interface LogoutOptions {
|
|
68
|
+
/** Post-logout redirect URI */
|
|
69
|
+
returnTo?: string;
|
|
70
|
+
/** Include id_token_hint in logout request */
|
|
71
|
+
idTokenHint?: string;
|
|
72
|
+
}
|
|
73
|
+
interface CallbackResult {
|
|
74
|
+
success: boolean;
|
|
75
|
+
user?: User;
|
|
76
|
+
accessToken?: string;
|
|
77
|
+
idToken?: string;
|
|
78
|
+
refreshToken?: string;
|
|
79
|
+
error?: string;
|
|
80
|
+
errorDescription?: string;
|
|
81
|
+
}
|
|
82
|
+
interface OIDCDiscovery {
|
|
83
|
+
issuer: string;
|
|
84
|
+
authorization_endpoint: string;
|
|
85
|
+
token_endpoint: string;
|
|
86
|
+
userinfo_endpoint: string;
|
|
87
|
+
jwks_uri: string;
|
|
88
|
+
end_session_endpoint?: string;
|
|
89
|
+
registration_endpoint?: string;
|
|
90
|
+
scopes_supported: string[];
|
|
91
|
+
response_types_supported: string[];
|
|
92
|
+
grant_types_supported: string[];
|
|
93
|
+
token_endpoint_auth_methods_supported: string[];
|
|
94
|
+
code_challenge_methods_supported?: string[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Stuffle IAM Client
|
|
99
|
+
*
|
|
100
|
+
* OIDC/OAuth2 client for browser-based applications.
|
|
101
|
+
* Supports authorization code flow with PKCE.
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
declare class StuffleIAMClient {
|
|
105
|
+
private config;
|
|
106
|
+
private storage;
|
|
107
|
+
private discovery;
|
|
108
|
+
private refreshTimer;
|
|
109
|
+
private listeners;
|
|
110
|
+
constructor(config: StuffleIAMConfig);
|
|
111
|
+
/**
|
|
112
|
+
* Fetch OIDC discovery document
|
|
113
|
+
*/
|
|
114
|
+
getDiscovery(): Promise<OIDCDiscovery>;
|
|
115
|
+
/**
|
|
116
|
+
* Start login flow - redirects to authorization endpoint
|
|
117
|
+
*/
|
|
118
|
+
login(options?: LoginOptions): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Alias for login({ signup: true })
|
|
121
|
+
*/
|
|
122
|
+
signup(options?: Omit<LoginOptions, 'signup'>): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Handle callback from authorization server
|
|
125
|
+
*/
|
|
126
|
+
handleCallback(url?: string): Promise<CallbackResult>;
|
|
127
|
+
/**
|
|
128
|
+
* Exchange authorization code for tokens
|
|
129
|
+
*/
|
|
130
|
+
private exchangeCode;
|
|
131
|
+
/**
|
|
132
|
+
* Refresh access token using refresh token
|
|
133
|
+
*/
|
|
134
|
+
refreshToken(): Promise<TokenResponse | null>;
|
|
135
|
+
/**
|
|
136
|
+
* Logout - end session
|
|
137
|
+
*/
|
|
138
|
+
logout(options?: LogoutOptions): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Get current access token (refreshes if needed)
|
|
141
|
+
*/
|
|
142
|
+
getAccessToken(): Promise<string | null>;
|
|
143
|
+
/**
|
|
144
|
+
* Get current user from stored ID token
|
|
145
|
+
*/
|
|
146
|
+
getUser(): User | null;
|
|
147
|
+
/**
|
|
148
|
+
* Fetch user info from userinfo endpoint
|
|
149
|
+
*/
|
|
150
|
+
fetchUserInfo(accessToken?: string): Promise<User | null>;
|
|
151
|
+
/**
|
|
152
|
+
* Check if user is authenticated
|
|
153
|
+
*/
|
|
154
|
+
isAuthenticated(): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Get current auth state
|
|
157
|
+
*/
|
|
158
|
+
getAuthState(): AuthState;
|
|
159
|
+
/**
|
|
160
|
+
* Subscribe to auth state changes
|
|
161
|
+
*/
|
|
162
|
+
subscribe(listener: (state: AuthState) => void): () => void;
|
|
163
|
+
/**
|
|
164
|
+
* Store tokens in storage
|
|
165
|
+
*/
|
|
166
|
+
private storeTokens;
|
|
167
|
+
/**
|
|
168
|
+
* Clear all stored tokens
|
|
169
|
+
*/
|
|
170
|
+
private clearTokens;
|
|
171
|
+
/**
|
|
172
|
+
* Setup auto-refresh timer
|
|
173
|
+
*/
|
|
174
|
+
private setupAutoRefresh;
|
|
175
|
+
/**
|
|
176
|
+
* Notify all listeners of state change
|
|
177
|
+
*/
|
|
178
|
+
private notifyListeners;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Create a new Stuffle IAM client instance
|
|
182
|
+
*/
|
|
183
|
+
declare function createStuffleIAMClient(config: StuffleIAMConfig): StuffleIAMClient;
|
|
184
|
+
|
|
185
|
+
export { type AuthState as A, type CallbackResult as C, type LoginOptions as L, type OIDCDiscovery as O, StuffleIAMClient as S, type TokenResponse as T, type User as U, type StuffleIAMConfig as a, type LogoutOptions as b, createStuffleIAMClient as c };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stuffle IAM SDK Types
|
|
3
|
+
*/
|
|
4
|
+
interface StuffleIAMConfig {
|
|
5
|
+
/** IAM server base URL (e.g., http://localhost:5000) */
|
|
6
|
+
issuer: string;
|
|
7
|
+
/** OAuth2 client ID */
|
|
8
|
+
clientId: string;
|
|
9
|
+
/** Redirect URI after login */
|
|
10
|
+
redirectUri: string;
|
|
11
|
+
/** Requested scopes (default: openid profile email) */
|
|
12
|
+
scopes?: string[];
|
|
13
|
+
/** Post-logout redirect URI */
|
|
14
|
+
postLogoutRedirectUri?: string;
|
|
15
|
+
/** Enable PKCE (default: true, recommended for SPAs) */
|
|
16
|
+
usePkce?: boolean;
|
|
17
|
+
/** Storage type for tokens (default: sessionStorage) */
|
|
18
|
+
storage?: 'localStorage' | 'sessionStorage' | 'memory';
|
|
19
|
+
/** Auto-refresh tokens before expiry (default: true) */
|
|
20
|
+
autoRefresh?: boolean;
|
|
21
|
+
/** Seconds before expiry to trigger refresh (default: 60) */
|
|
22
|
+
refreshThreshold?: number;
|
|
23
|
+
}
|
|
24
|
+
interface TokenResponse {
|
|
25
|
+
access_token: string;
|
|
26
|
+
token_type: string;
|
|
27
|
+
expires_in: number;
|
|
28
|
+
refresh_token?: string;
|
|
29
|
+
id_token?: string;
|
|
30
|
+
scope?: string;
|
|
31
|
+
}
|
|
32
|
+
interface User {
|
|
33
|
+
sub: string;
|
|
34
|
+
email?: string;
|
|
35
|
+
email_verified?: boolean;
|
|
36
|
+
name?: string;
|
|
37
|
+
given_name?: string;
|
|
38
|
+
family_name?: string;
|
|
39
|
+
picture?: string;
|
|
40
|
+
username?: string;
|
|
41
|
+
roles?: string[];
|
|
42
|
+
tenantId?: string;
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
interface AuthState {
|
|
46
|
+
isAuthenticated: boolean;
|
|
47
|
+
isLoading: boolean;
|
|
48
|
+
user: User | null;
|
|
49
|
+
accessToken: string | null;
|
|
50
|
+
idToken: string | null;
|
|
51
|
+
error: Error | null;
|
|
52
|
+
}
|
|
53
|
+
interface LoginOptions {
|
|
54
|
+
/** Additional scopes to request */
|
|
55
|
+
scopes?: string[];
|
|
56
|
+
/** State parameter (auto-generated if not provided) */
|
|
57
|
+
state?: string;
|
|
58
|
+
/** Nonce for ID token validation */
|
|
59
|
+
nonce?: string;
|
|
60
|
+
/** Redirect to signup instead of login */
|
|
61
|
+
signup?: boolean;
|
|
62
|
+
/** Prompt parameter (none, login, consent, select_account) */
|
|
63
|
+
prompt?: 'none' | 'login' | 'consent' | 'select_account';
|
|
64
|
+
/** Login hint (email or username) */
|
|
65
|
+
loginHint?: string;
|
|
66
|
+
}
|
|
67
|
+
interface LogoutOptions {
|
|
68
|
+
/** Post-logout redirect URI */
|
|
69
|
+
returnTo?: string;
|
|
70
|
+
/** Include id_token_hint in logout request */
|
|
71
|
+
idTokenHint?: string;
|
|
72
|
+
}
|
|
73
|
+
interface CallbackResult {
|
|
74
|
+
success: boolean;
|
|
75
|
+
user?: User;
|
|
76
|
+
accessToken?: string;
|
|
77
|
+
idToken?: string;
|
|
78
|
+
refreshToken?: string;
|
|
79
|
+
error?: string;
|
|
80
|
+
errorDescription?: string;
|
|
81
|
+
}
|
|
82
|
+
interface OIDCDiscovery {
|
|
83
|
+
issuer: string;
|
|
84
|
+
authorization_endpoint: string;
|
|
85
|
+
token_endpoint: string;
|
|
86
|
+
userinfo_endpoint: string;
|
|
87
|
+
jwks_uri: string;
|
|
88
|
+
end_session_endpoint?: string;
|
|
89
|
+
registration_endpoint?: string;
|
|
90
|
+
scopes_supported: string[];
|
|
91
|
+
response_types_supported: string[];
|
|
92
|
+
grant_types_supported: string[];
|
|
93
|
+
token_endpoint_auth_methods_supported: string[];
|
|
94
|
+
code_challenge_methods_supported?: string[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Stuffle IAM Client
|
|
99
|
+
*
|
|
100
|
+
* OIDC/OAuth2 client for browser-based applications.
|
|
101
|
+
* Supports authorization code flow with PKCE.
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
declare class StuffleIAMClient {
|
|
105
|
+
private config;
|
|
106
|
+
private storage;
|
|
107
|
+
private discovery;
|
|
108
|
+
private refreshTimer;
|
|
109
|
+
private listeners;
|
|
110
|
+
constructor(config: StuffleIAMConfig);
|
|
111
|
+
/**
|
|
112
|
+
* Fetch OIDC discovery document
|
|
113
|
+
*/
|
|
114
|
+
getDiscovery(): Promise<OIDCDiscovery>;
|
|
115
|
+
/**
|
|
116
|
+
* Start login flow - redirects to authorization endpoint
|
|
117
|
+
*/
|
|
118
|
+
login(options?: LoginOptions): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Alias for login({ signup: true })
|
|
121
|
+
*/
|
|
122
|
+
signup(options?: Omit<LoginOptions, 'signup'>): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Handle callback from authorization server
|
|
125
|
+
*/
|
|
126
|
+
handleCallback(url?: string): Promise<CallbackResult>;
|
|
127
|
+
/**
|
|
128
|
+
* Exchange authorization code for tokens
|
|
129
|
+
*/
|
|
130
|
+
private exchangeCode;
|
|
131
|
+
/**
|
|
132
|
+
* Refresh access token using refresh token
|
|
133
|
+
*/
|
|
134
|
+
refreshToken(): Promise<TokenResponse | null>;
|
|
135
|
+
/**
|
|
136
|
+
* Logout - end session
|
|
137
|
+
*/
|
|
138
|
+
logout(options?: LogoutOptions): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Get current access token (refreshes if needed)
|
|
141
|
+
*/
|
|
142
|
+
getAccessToken(): Promise<string | null>;
|
|
143
|
+
/**
|
|
144
|
+
* Get current user from stored ID token
|
|
145
|
+
*/
|
|
146
|
+
getUser(): User | null;
|
|
147
|
+
/**
|
|
148
|
+
* Fetch user info from userinfo endpoint
|
|
149
|
+
*/
|
|
150
|
+
fetchUserInfo(accessToken?: string): Promise<User | null>;
|
|
151
|
+
/**
|
|
152
|
+
* Check if user is authenticated
|
|
153
|
+
*/
|
|
154
|
+
isAuthenticated(): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Get current auth state
|
|
157
|
+
*/
|
|
158
|
+
getAuthState(): AuthState;
|
|
159
|
+
/**
|
|
160
|
+
* Subscribe to auth state changes
|
|
161
|
+
*/
|
|
162
|
+
subscribe(listener: (state: AuthState) => void): () => void;
|
|
163
|
+
/**
|
|
164
|
+
* Store tokens in storage
|
|
165
|
+
*/
|
|
166
|
+
private storeTokens;
|
|
167
|
+
/**
|
|
168
|
+
* Clear all stored tokens
|
|
169
|
+
*/
|
|
170
|
+
private clearTokens;
|
|
171
|
+
/**
|
|
172
|
+
* Setup auto-refresh timer
|
|
173
|
+
*/
|
|
174
|
+
private setupAutoRefresh;
|
|
175
|
+
/**
|
|
176
|
+
* Notify all listeners of state change
|
|
177
|
+
*/
|
|
178
|
+
private notifyListeners;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Create a new Stuffle IAM client instance
|
|
182
|
+
*/
|
|
183
|
+
declare function createStuffleIAMClient(config: StuffleIAMConfig): StuffleIAMClient;
|
|
184
|
+
|
|
185
|
+
export { type AuthState as A, type CallbackResult as C, type LoginOptions as L, type OIDCDiscovery as O, StuffleIAMClient as S, type TokenResponse as T, type User as U, type StuffleIAMConfig as a, type LogoutOptions as b, createStuffleIAMClient as c };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export { A as AuthState, C as CallbackResult, L as LoginOptions, b as LogoutOptions, O as OIDCDiscovery, S as StuffleIAMClient, a as StuffleIAMConfig, T as TokenResponse, U as User, c as createStuffleIAMClient } from './client-CTKWBZ26.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Utility functions for PKCE and crypto operations
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Generate a random string for state/nonce
|
|
8
|
+
*/
|
|
9
|
+
declare function generateRandomString(length?: number): string;
|
|
10
|
+
/**
|
|
11
|
+
* Generate PKCE code verifier (43-128 characters)
|
|
12
|
+
*/
|
|
13
|
+
declare function generateCodeVerifier(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generate PKCE code challenge from verifier
|
|
16
|
+
*/
|
|
17
|
+
declare function generateCodeChallenge(verifier: string): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Decode JWT payload (without verification)
|
|
20
|
+
*/
|
|
21
|
+
declare function decodeJwtPayload<T = Record<string, unknown>>(token: string): T | null;
|
|
22
|
+
/**
|
|
23
|
+
* Check if token is expired
|
|
24
|
+
*/
|
|
25
|
+
declare function isTokenExpired(token: string, thresholdSeconds?: number): boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Token storage abstraction
|
|
29
|
+
*/
|
|
30
|
+
interface TokenStorage {
|
|
31
|
+
get(key: string): string | null;
|
|
32
|
+
set(key: string, value: string): void;
|
|
33
|
+
remove(key: string): void;
|
|
34
|
+
clear(): void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get storage adapter based on type
|
|
38
|
+
*/
|
|
39
|
+
declare function getStorage(type: 'localStorage' | 'sessionStorage' | 'memory'): TokenStorage;
|
|
40
|
+
|
|
41
|
+
export { type TokenStorage, decodeJwtPayload, generateCodeChallenge, generateCodeVerifier, generateRandomString, getStorage, isTokenExpired };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export { A as AuthState, C as CallbackResult, L as LoginOptions, b as LogoutOptions, O as OIDCDiscovery, S as StuffleIAMClient, a as StuffleIAMConfig, T as TokenResponse, U as User, c as createStuffleIAMClient } from './client-CTKWBZ26.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Utility functions for PKCE and crypto operations
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Generate a random string for state/nonce
|
|
8
|
+
*/
|
|
9
|
+
declare function generateRandomString(length?: number): string;
|
|
10
|
+
/**
|
|
11
|
+
* Generate PKCE code verifier (43-128 characters)
|
|
12
|
+
*/
|
|
13
|
+
declare function generateCodeVerifier(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generate PKCE code challenge from verifier
|
|
16
|
+
*/
|
|
17
|
+
declare function generateCodeChallenge(verifier: string): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Decode JWT payload (without verification)
|
|
20
|
+
*/
|
|
21
|
+
declare function decodeJwtPayload<T = Record<string, unknown>>(token: string): T | null;
|
|
22
|
+
/**
|
|
23
|
+
* Check if token is expired
|
|
24
|
+
*/
|
|
25
|
+
declare function isTokenExpired(token: string, thresholdSeconds?: number): boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Token storage abstraction
|
|
29
|
+
*/
|
|
30
|
+
interface TokenStorage {
|
|
31
|
+
get(key: string): string | null;
|
|
32
|
+
set(key: string, value: string): void;
|
|
33
|
+
remove(key: string): void;
|
|
34
|
+
clear(): void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get storage adapter based on type
|
|
38
|
+
*/
|
|
39
|
+
declare function getStorage(type: 'localStorage' | 'sessionStorage' | 'memory'): TokenStorage;
|
|
40
|
+
|
|
41
|
+
export { type TokenStorage, decodeJwtPayload, generateCodeChallenge, generateCodeVerifier, generateRandomString, getStorage, isTokenExpired };
|