@classic-homes/auth 0.1.24 → 0.1.26
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/auth.svelte-PKMR4LYT.js +3 -0
- package/dist/chunk-DCGC6CNV.js +98 -0
- package/dist/chunk-IO2LIH4I.js +66 -0
- package/dist/chunk-MI4B4ZRK.js +558 -0
- package/dist/chunk-MY664247.js +306 -0
- package/dist/chunk-U2YM3E3Q.js +269 -0
- package/dist/core/index.js +3 -1279
- package/dist/index.js +5 -1346
- package/dist/svelte/index.js +4 -988
- package/dist/testing/index.js +6 -30
- package/package.json +1 -1
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { authApi } from './chunk-MI4B4ZRK.js';
|
|
2
|
+
|
|
3
|
+
// src/core/guards.ts
|
|
4
|
+
function isMfaChallengeResponse(response) {
|
|
5
|
+
return "requiresMFA" in response && response.requiresMFA === true || "mfaRequired" in response && response.mfaRequired === true;
|
|
6
|
+
}
|
|
7
|
+
function isLoginSuccessResponse(response) {
|
|
8
|
+
return "accessToken" in response && "user" in response && !isMfaChallengeResponse(response);
|
|
9
|
+
}
|
|
10
|
+
function getMfaToken(response) {
|
|
11
|
+
return response.mfaToken ?? response.mfaChallengeToken;
|
|
12
|
+
}
|
|
13
|
+
function getAvailableMethods(response) {
|
|
14
|
+
return response.availableMethods ?? ["totp"];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/core/service.ts
|
|
18
|
+
var AuthService = class {
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Authentication
|
|
21
|
+
// ============================================================================
|
|
22
|
+
/**
|
|
23
|
+
* Login with username and password.
|
|
24
|
+
* By default, automatically sets the auth state on successful login (unless MFA is required).
|
|
25
|
+
* @param credentials - Username and password
|
|
26
|
+
* @param options - Optional settings for login behavior
|
|
27
|
+
*/
|
|
28
|
+
async login(credentials, options) {
|
|
29
|
+
const response = await authApi.login(credentials);
|
|
30
|
+
if (options?.autoSetAuth !== false && !isMfaChallengeResponse(response)) {
|
|
31
|
+
try {
|
|
32
|
+
const { authStore } = await import('./auth.svelte-PKMR4LYT.js');
|
|
33
|
+
authStore.setAuth(
|
|
34
|
+
response.accessToken,
|
|
35
|
+
response.refreshToken,
|
|
36
|
+
response.user,
|
|
37
|
+
response.sessionToken
|
|
38
|
+
);
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return response;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Logout the current user.
|
|
46
|
+
* Returns SSO logout URL if applicable for SSO users.
|
|
47
|
+
*/
|
|
48
|
+
async logout() {
|
|
49
|
+
return await authApi.logout();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Register a new user.
|
|
53
|
+
*/
|
|
54
|
+
async register(data) {
|
|
55
|
+
return await authApi.register(data);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Request a password reset email.
|
|
59
|
+
*/
|
|
60
|
+
async forgotPassword(email) {
|
|
61
|
+
await authApi.forgotPassword(email);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Reset password with a token.
|
|
65
|
+
*/
|
|
66
|
+
async resetPassword(token, newPassword) {
|
|
67
|
+
await authApi.resetPassword(token, newPassword);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Change the current user's password.
|
|
71
|
+
*/
|
|
72
|
+
async changePassword(currentPassword, newPassword) {
|
|
73
|
+
await authApi.changePassword({ currentPassword, newPassword });
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Refresh the access token.
|
|
77
|
+
*/
|
|
78
|
+
async refreshToken(refreshToken) {
|
|
79
|
+
return await authApi.refreshToken(refreshToken);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Initiate SSO login (redirects to SSO provider).
|
|
83
|
+
* @param options.callbackUrl - The URL where the SSO provider should redirect after auth
|
|
84
|
+
* @param options.redirectUrl - The final URL to redirect to after processing the callback
|
|
85
|
+
*/
|
|
86
|
+
initiateSSOLogin(options) {
|
|
87
|
+
authApi.initiateSSOLogin(options);
|
|
88
|
+
}
|
|
89
|
+
// ============================================================================
|
|
90
|
+
// Profile
|
|
91
|
+
// ============================================================================
|
|
92
|
+
/**
|
|
93
|
+
* Get the current user's profile.
|
|
94
|
+
*/
|
|
95
|
+
async getProfile(customFetch) {
|
|
96
|
+
return await authApi.getProfile(customFetch);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Update the current user's profile.
|
|
100
|
+
*/
|
|
101
|
+
async updateProfile(data) {
|
|
102
|
+
return await authApi.updateProfile(data);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Resend email verification.
|
|
106
|
+
*/
|
|
107
|
+
async resendVerification() {
|
|
108
|
+
await authApi.resendVerification();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Verify email with a token.
|
|
112
|
+
*/
|
|
113
|
+
async verifyEmail(token) {
|
|
114
|
+
return await authApi.verifyEmail(token);
|
|
115
|
+
}
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// Session Management
|
|
118
|
+
// ============================================================================
|
|
119
|
+
/**
|
|
120
|
+
* Get all active sessions.
|
|
121
|
+
*/
|
|
122
|
+
async getSessions(customFetch) {
|
|
123
|
+
return await authApi.getSessions(customFetch);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Revoke a specific session.
|
|
127
|
+
*/
|
|
128
|
+
async revokeSession(sessionId) {
|
|
129
|
+
await authApi.revokeSession(sessionId);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Revoke all sessions except the current one.
|
|
133
|
+
*/
|
|
134
|
+
async revokeAllSessions() {
|
|
135
|
+
await authApi.revokeAllSessions();
|
|
136
|
+
}
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// API Key Management
|
|
139
|
+
// ============================================================================
|
|
140
|
+
/**
|
|
141
|
+
* Get all API keys.
|
|
142
|
+
*/
|
|
143
|
+
async getApiKeys(customFetch) {
|
|
144
|
+
return await authApi.getApiKeys(customFetch);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Create a new API key.
|
|
148
|
+
*/
|
|
149
|
+
async createApiKey(data) {
|
|
150
|
+
return await authApi.createApiKey(data);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Revoke an API key.
|
|
154
|
+
*/
|
|
155
|
+
async revokeApiKey(keyId) {
|
|
156
|
+
await authApi.revokeApiKey(keyId);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Update an API key's name.
|
|
160
|
+
*/
|
|
161
|
+
async updateApiKey(keyId, name) {
|
|
162
|
+
await authApi.updateApiKey(keyId, { name });
|
|
163
|
+
}
|
|
164
|
+
// ============================================================================
|
|
165
|
+
// MFA Management
|
|
166
|
+
// ============================================================================
|
|
167
|
+
/**
|
|
168
|
+
* Get MFA status for the current user.
|
|
169
|
+
*/
|
|
170
|
+
async getMFAStatus() {
|
|
171
|
+
return await authApi.getMFAStatus();
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Setup MFA (get QR code and backup codes).
|
|
175
|
+
*/
|
|
176
|
+
async setupMFA() {
|
|
177
|
+
return await authApi.setupMFA();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Verify MFA setup with a code.
|
|
181
|
+
*/
|
|
182
|
+
async verifyMFASetup(code) {
|
|
183
|
+
await authApi.verifyMFASetup(code);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Disable MFA.
|
|
187
|
+
*/
|
|
188
|
+
async disableMFA(password) {
|
|
189
|
+
await authApi.disableMFA(password);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Regenerate MFA backup codes.
|
|
193
|
+
*/
|
|
194
|
+
async regenerateBackupCodes(password) {
|
|
195
|
+
return await authApi.regenerateBackupCodes(password);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Verify MFA challenge during login.
|
|
199
|
+
* By default, automatically sets the auth state on successful verification.
|
|
200
|
+
* @param data - MFA challenge data including token and code
|
|
201
|
+
* @param options - Optional settings for verification behavior
|
|
202
|
+
*/
|
|
203
|
+
async verifyMFAChallenge(data, options) {
|
|
204
|
+
const response = await authApi.verifyMFAChallenge(data);
|
|
205
|
+
if (options?.autoSetAuth !== false) {
|
|
206
|
+
try {
|
|
207
|
+
const { authStore } = await import('./auth.svelte-PKMR4LYT.js');
|
|
208
|
+
authStore.setAuth(
|
|
209
|
+
response.accessToken,
|
|
210
|
+
response.refreshToken,
|
|
211
|
+
response.user,
|
|
212
|
+
response.sessionToken
|
|
213
|
+
);
|
|
214
|
+
} catch {
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return response;
|
|
218
|
+
}
|
|
219
|
+
// ============================================================================
|
|
220
|
+
// Device Management
|
|
221
|
+
// ============================================================================
|
|
222
|
+
/**
|
|
223
|
+
* Get all devices.
|
|
224
|
+
*/
|
|
225
|
+
async getDevices(customFetch) {
|
|
226
|
+
return await authApi.getDevices(customFetch);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Trust a device.
|
|
230
|
+
*/
|
|
231
|
+
async trustDevice(deviceId) {
|
|
232
|
+
await authApi.trustDevice(deviceId);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Revoke device trust.
|
|
236
|
+
*/
|
|
237
|
+
async revokeDevice(deviceId) {
|
|
238
|
+
await authApi.revokeDevice(deviceId);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Remove a device completely.
|
|
242
|
+
*/
|
|
243
|
+
async removeDevice(deviceId) {
|
|
244
|
+
await authApi.removeDevice(deviceId);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Approve a device with a token.
|
|
248
|
+
*/
|
|
249
|
+
async approveDevice(token) {
|
|
250
|
+
return await authApi.approveDevice(token);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Block a device with a token.
|
|
254
|
+
*/
|
|
255
|
+
async blockDevice(token) {
|
|
256
|
+
return await authApi.blockDevice(token);
|
|
257
|
+
}
|
|
258
|
+
// ============================================================================
|
|
259
|
+
// Preferences
|
|
260
|
+
// ============================================================================
|
|
261
|
+
/**
|
|
262
|
+
* Get user preferences.
|
|
263
|
+
*/
|
|
264
|
+
async getPreferences(customFetch) {
|
|
265
|
+
return await authApi.getPreferences(customFetch);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Update user preferences.
|
|
269
|
+
*/
|
|
270
|
+
async updatePreferences(data) {
|
|
271
|
+
await authApi.updatePreferences(data);
|
|
272
|
+
}
|
|
273
|
+
// ============================================================================
|
|
274
|
+
// SSO / Linked Accounts
|
|
275
|
+
// ============================================================================
|
|
276
|
+
/**
|
|
277
|
+
* Get SSO linked accounts.
|
|
278
|
+
*/
|
|
279
|
+
async getLinkedAccounts(customFetch) {
|
|
280
|
+
return await authApi.getSSOAccounts(customFetch);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Link an SSO account (redirects to SSO provider).
|
|
284
|
+
*/
|
|
285
|
+
async linkAccount(provider = "authentik") {
|
|
286
|
+
await authApi.linkSSOAccount(provider);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Unlink an SSO account.
|
|
290
|
+
*/
|
|
291
|
+
async unlinkAccount(provider, password) {
|
|
292
|
+
await authApi.unlinkSSOAccount(provider, password);
|
|
293
|
+
}
|
|
294
|
+
// ============================================================================
|
|
295
|
+
// Security Events
|
|
296
|
+
// ============================================================================
|
|
297
|
+
/**
|
|
298
|
+
* Get security event history.
|
|
299
|
+
*/
|
|
300
|
+
async getSecurityEvents(params, customFetch) {
|
|
301
|
+
return await authApi.getSecurityEvents(params, customFetch);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
var authService = new AuthService();
|
|
305
|
+
|
|
306
|
+
export { AuthService, authService, getAvailableMethods, getMfaToken, isLoginSuccessResponse, isMfaChallengeResponse };
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { authApi } from './chunk-MI4B4ZRK.js';
|
|
2
|
+
import { decodeJWT, isInitialized, getConfig, getStorage, getDefaultStorage } from './chunk-DCGC6CNV.js';
|
|
3
|
+
|
|
4
|
+
// src/svelte/stores/auth.svelte.ts
|
|
5
|
+
function getStorageKey() {
|
|
6
|
+
return isInitialized() ? getConfig().storageKey ?? "classic_auth" : "classic_auth";
|
|
7
|
+
}
|
|
8
|
+
function getStorageAdapter() {
|
|
9
|
+
return isInitialized() ? getStorage() : getDefaultStorage();
|
|
10
|
+
}
|
|
11
|
+
function loadAuthFromStorage() {
|
|
12
|
+
try {
|
|
13
|
+
const storage = getStorageAdapter();
|
|
14
|
+
const data = storage.getItem(getStorageKey());
|
|
15
|
+
if (!data) {
|
|
16
|
+
return {
|
|
17
|
+
accessToken: null,
|
|
18
|
+
refreshToken: null,
|
|
19
|
+
user: null,
|
|
20
|
+
isAuthenticated: false
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const parsed = JSON.parse(data);
|
|
24
|
+
return {
|
|
25
|
+
accessToken: parsed.accessToken ?? null,
|
|
26
|
+
refreshToken: parsed.refreshToken ?? null,
|
|
27
|
+
user: parsed.user ?? null,
|
|
28
|
+
isAuthenticated: !!parsed.accessToken && !!parsed.user
|
|
29
|
+
};
|
|
30
|
+
} catch {
|
|
31
|
+
return {
|
|
32
|
+
accessToken: null,
|
|
33
|
+
refreshToken: null,
|
|
34
|
+
user: null,
|
|
35
|
+
isAuthenticated: false
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function saveAuthToStorage(state) {
|
|
40
|
+
try {
|
|
41
|
+
const storage = getStorageAdapter();
|
|
42
|
+
const key = getStorageKey();
|
|
43
|
+
if (!state.accessToken) {
|
|
44
|
+
storage.removeItem(key);
|
|
45
|
+
} else {
|
|
46
|
+
storage.setItem(key, JSON.stringify(state));
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
var AuthStore = class {
|
|
52
|
+
constructor() {
|
|
53
|
+
this.subscribers = /* @__PURE__ */ new Set();
|
|
54
|
+
this.state = loadAuthFromStorage();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Subscribe to state changes (Svelte store contract).
|
|
58
|
+
*/
|
|
59
|
+
subscribe(subscriber) {
|
|
60
|
+
this.subscribers.add(subscriber);
|
|
61
|
+
subscriber(this.state);
|
|
62
|
+
return () => this.subscribers.delete(subscriber);
|
|
63
|
+
}
|
|
64
|
+
notify() {
|
|
65
|
+
this.subscribers.forEach((sub) => sub(this.state));
|
|
66
|
+
}
|
|
67
|
+
// Getters for direct access
|
|
68
|
+
get accessToken() {
|
|
69
|
+
return this.state.accessToken;
|
|
70
|
+
}
|
|
71
|
+
get refreshToken() {
|
|
72
|
+
return this.state.refreshToken;
|
|
73
|
+
}
|
|
74
|
+
get user() {
|
|
75
|
+
return this.state.user;
|
|
76
|
+
}
|
|
77
|
+
get isAuthenticated() {
|
|
78
|
+
return this.state.isAuthenticated;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get the current auth state snapshot.
|
|
82
|
+
*/
|
|
83
|
+
getState() {
|
|
84
|
+
return { ...this.state };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Set auth data after successful login.
|
|
88
|
+
*/
|
|
89
|
+
setAuth(accessToken, refreshToken, user, sessionToken) {
|
|
90
|
+
const jwtPayload = decodeJWT(accessToken);
|
|
91
|
+
const userWithPermissions = {
|
|
92
|
+
...user,
|
|
93
|
+
permissions: user.permissions || jwtPayload?.permissions || [],
|
|
94
|
+
roles: user.roles || jwtPayload?.roles || (user.role ? [user.role] : [])
|
|
95
|
+
};
|
|
96
|
+
this.state = {
|
|
97
|
+
accessToken,
|
|
98
|
+
refreshToken,
|
|
99
|
+
user: userWithPermissions,
|
|
100
|
+
isAuthenticated: true
|
|
101
|
+
};
|
|
102
|
+
saveAuthToStorage(this.state);
|
|
103
|
+
if (sessionToken && typeof window !== "undefined") {
|
|
104
|
+
getStorageAdapter().setItem("sessionToken", sessionToken);
|
|
105
|
+
}
|
|
106
|
+
if (typeof window !== "undefined") {
|
|
107
|
+
window.dispatchEvent(
|
|
108
|
+
new CustomEvent("auth:login", {
|
|
109
|
+
detail: { user: userWithPermissions }
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
this.notify();
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Update tokens (e.g., after refresh).
|
|
117
|
+
*/
|
|
118
|
+
updateTokens(accessToken, refreshToken) {
|
|
119
|
+
const jwtPayload = decodeJWT(accessToken);
|
|
120
|
+
const updatedUser = this.state.user ? {
|
|
121
|
+
...this.state.user,
|
|
122
|
+
permissions: jwtPayload?.permissions || this.state.user.permissions || [],
|
|
123
|
+
roles: jwtPayload?.roles || this.state.user.roles || (this.state.user.role ? [this.state.user.role] : [])
|
|
124
|
+
} : null;
|
|
125
|
+
this.state = {
|
|
126
|
+
...this.state,
|
|
127
|
+
accessToken,
|
|
128
|
+
refreshToken,
|
|
129
|
+
user: updatedUser
|
|
130
|
+
};
|
|
131
|
+
saveAuthToStorage(this.state);
|
|
132
|
+
if (typeof window !== "undefined") {
|
|
133
|
+
window.dispatchEvent(new CustomEvent("auth:token-refresh"));
|
|
134
|
+
}
|
|
135
|
+
this.notify();
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Update user data (e.g., after profile update).
|
|
139
|
+
*/
|
|
140
|
+
updateUser(user) {
|
|
141
|
+
const jwtPayload = this.state.accessToken ? decodeJWT(this.state.accessToken) : null;
|
|
142
|
+
const updatedUser = {
|
|
143
|
+
...user,
|
|
144
|
+
permissions: user.permissions || jwtPayload?.permissions || [],
|
|
145
|
+
roles: user.roles || jwtPayload?.roles || (user.role ? [user.role] : [])
|
|
146
|
+
};
|
|
147
|
+
this.state = {
|
|
148
|
+
...this.state,
|
|
149
|
+
user: updatedUser
|
|
150
|
+
};
|
|
151
|
+
saveAuthToStorage(this.state);
|
|
152
|
+
if (typeof window !== "undefined") {
|
|
153
|
+
window.dispatchEvent(
|
|
154
|
+
new CustomEvent("auth:profile-update", {
|
|
155
|
+
detail: { user: updatedUser }
|
|
156
|
+
})
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
this.notify();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Clear auth state (logout).
|
|
163
|
+
*/
|
|
164
|
+
logout() {
|
|
165
|
+
this.state = {
|
|
166
|
+
accessToken: null,
|
|
167
|
+
refreshToken: null,
|
|
168
|
+
user: null,
|
|
169
|
+
isAuthenticated: false
|
|
170
|
+
};
|
|
171
|
+
const storage = getStorageAdapter();
|
|
172
|
+
storage.removeItem(getStorageKey());
|
|
173
|
+
storage.removeItem("sessionToken");
|
|
174
|
+
if (typeof window !== "undefined") {
|
|
175
|
+
window.dispatchEvent(new CustomEvent("auth:logout"));
|
|
176
|
+
}
|
|
177
|
+
if (isInitialized()) {
|
|
178
|
+
getConfig().onLogout?.();
|
|
179
|
+
}
|
|
180
|
+
this.notify();
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Logout with SSO support.
|
|
184
|
+
* Calls the logout API and returns the SSO logout URL if applicable.
|
|
185
|
+
* Clears local state regardless of API response.
|
|
186
|
+
*/
|
|
187
|
+
async logoutWithSSO() {
|
|
188
|
+
try {
|
|
189
|
+
const response = await authApi.logout();
|
|
190
|
+
this.logout();
|
|
191
|
+
if (response?.ssoLogout && response?.logoutUrl) {
|
|
192
|
+
return { ssoLogoutUrl: response.logoutUrl };
|
|
193
|
+
}
|
|
194
|
+
} catch {
|
|
195
|
+
this.logout();
|
|
196
|
+
}
|
|
197
|
+
return {};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Check if user has a specific permission.
|
|
201
|
+
*/
|
|
202
|
+
hasPermission(permission) {
|
|
203
|
+
return this.state.user?.permissions?.includes(permission) ?? false;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check if user has a specific role.
|
|
207
|
+
*/
|
|
208
|
+
hasRole(role) {
|
|
209
|
+
return this.state.user?.roles?.includes(role) ?? false;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Check if user has any of the specified roles.
|
|
213
|
+
*/
|
|
214
|
+
hasAnyRole(roles) {
|
|
215
|
+
return roles.some((role) => this.state.user?.roles?.includes(role)) ?? false;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Check if user has all of the specified roles.
|
|
219
|
+
*/
|
|
220
|
+
hasAllRoles(roles) {
|
|
221
|
+
return roles.every((role) => this.state.user?.roles?.includes(role)) ?? false;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Check if user has any of the specified permissions.
|
|
225
|
+
*/
|
|
226
|
+
hasAnyPermission(permissions) {
|
|
227
|
+
return permissions.some((perm) => this.state.user?.permissions?.includes(perm)) ?? false;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Check if user has all of the specified permissions.
|
|
231
|
+
*/
|
|
232
|
+
hasAllPermissions(permissions) {
|
|
233
|
+
return permissions.every((perm) => this.state.user?.permissions?.includes(perm)) ?? false;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Re-hydrate state from storage (useful after config changes).
|
|
237
|
+
*/
|
|
238
|
+
rehydrate() {
|
|
239
|
+
this.state = loadAuthFromStorage();
|
|
240
|
+
this.notify();
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
var authStore = new AuthStore();
|
|
244
|
+
var authActions = {
|
|
245
|
+
setAuth: (accessToken, refreshToken, user, sessionToken) => authStore.setAuth(accessToken, refreshToken, user, sessionToken),
|
|
246
|
+
updateTokens: (accessToken, refreshToken) => authStore.updateTokens(accessToken, refreshToken),
|
|
247
|
+
updateUser: (user) => authStore.updateUser(user),
|
|
248
|
+
logout: () => authStore.logout(),
|
|
249
|
+
logoutWithSSO: () => authStore.logoutWithSSO(),
|
|
250
|
+
hasPermission: (permission) => authStore.hasPermission(permission),
|
|
251
|
+
hasRole: (role) => authStore.hasRole(role),
|
|
252
|
+
hasAnyRole: (roles) => authStore.hasAnyRole(roles),
|
|
253
|
+
hasAllRoles: (roles) => authStore.hasAllRoles(roles),
|
|
254
|
+
hasAnyPermission: (permissions) => authStore.hasAnyPermission(permissions),
|
|
255
|
+
hasAllPermissions: (permissions) => authStore.hasAllPermissions(permissions),
|
|
256
|
+
rehydrate: () => authStore.rehydrate()
|
|
257
|
+
};
|
|
258
|
+
var isAuthenticated = {
|
|
259
|
+
subscribe: (subscriber) => {
|
|
260
|
+
return authStore.subscribe((state) => subscriber(state.isAuthenticated));
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
var currentUser = {
|
|
264
|
+
subscribe: (subscriber) => {
|
|
265
|
+
return authStore.subscribe((state) => subscriber(state.user));
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
export { authActions, authStore, currentUser, isAuthenticated };
|