@decido/shell-auth 4.0.1 → 4.0.3
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 +172 -0
- package/dist/index.mjs +146 -0
- package/package.json +13 -6
- package/src/index.ts +0 -131
package/dist/index.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
secureStorage: () => secureStorage,
|
|
24
|
+
useAuthStore: () => useAuthStore
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
var import_zustand = require("zustand");
|
|
28
|
+
var import_middleware = require("zustand/middleware");
|
|
29
|
+
|
|
30
|
+
// src/secureStorage.ts
|
|
31
|
+
var import_idb_keyval = require("idb-keyval");
|
|
32
|
+
var import_tauri_bridge = require("@decido/tauri-bridge");
|
|
33
|
+
var import_tauri_bridge2 = require("@decido/tauri-bridge");
|
|
34
|
+
var obfuscate = (data) => {
|
|
35
|
+
if (typeof btoa === "undefined") return data;
|
|
36
|
+
return btoa(encodeURIComponent(data));
|
|
37
|
+
};
|
|
38
|
+
var deobfuscate = (data) => {
|
|
39
|
+
if (typeof atob === "undefined") return data;
|
|
40
|
+
try {
|
|
41
|
+
return decodeURIComponent(atob(data));
|
|
42
|
+
} catch {
|
|
43
|
+
return data;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var secureStorage = {
|
|
47
|
+
getItem: async (name) => {
|
|
48
|
+
try {
|
|
49
|
+
if ((0, import_tauri_bridge2.isTauri)()) {
|
|
50
|
+
const val2 = await import_tauri_bridge.secure.secureVault.getItem(name);
|
|
51
|
+
if (val2 !== null) return val2;
|
|
52
|
+
}
|
|
53
|
+
const val = await (0, import_idb_keyval.get)(name);
|
|
54
|
+
if (!val) return null;
|
|
55
|
+
return deobfuscate(val);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.error(`[SecureStorage] Failed to get item ${name}`, err);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
setItem: async (name, value) => {
|
|
62
|
+
try {
|
|
63
|
+
if ((0, import_tauri_bridge2.isTauri)()) {
|
|
64
|
+
await import_tauri_bridge.secure.secureVault.setItem(name, value);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const obfuscated = obfuscate(value);
|
|
68
|
+
await (0, import_idb_keyval.set)(name, obfuscated);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error(`[SecureStorage] Failed to set item ${name}`, err);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
removeItem: async (name) => {
|
|
74
|
+
try {
|
|
75
|
+
if ((0, import_tauri_bridge2.isTauri)()) {
|
|
76
|
+
await import_tauri_bridge.secure.secureVault.removeItem(name);
|
|
77
|
+
}
|
|
78
|
+
await (0, import_idb_keyval.del)(name);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error(`[SecureStorage] Failed to remove item ${name}`, err);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// src/index.ts
|
|
86
|
+
var useAuthStore = (0, import_zustand.create)()(
|
|
87
|
+
(0, import_middleware.persist)(
|
|
88
|
+
(set2, get2) => ({
|
|
89
|
+
isAuthenticated: false,
|
|
90
|
+
userRole: null,
|
|
91
|
+
userName: null,
|
|
92
|
+
availableLicenses: [],
|
|
93
|
+
activeContext: null,
|
|
94
|
+
hasCompletedWelcome: false,
|
|
95
|
+
hasSeenTour: false,
|
|
96
|
+
login: (role, name, licenses) => {
|
|
97
|
+
const defaultLicenses = licenses || [{
|
|
98
|
+
type: "personal",
|
|
99
|
+
id: "personal",
|
|
100
|
+
name: `${name}'s Private Space`
|
|
101
|
+
}];
|
|
102
|
+
set2({
|
|
103
|
+
isAuthenticated: true,
|
|
104
|
+
userRole: role,
|
|
105
|
+
userName: name,
|
|
106
|
+
availableLicenses: defaultLicenses,
|
|
107
|
+
activeContext: defaultLicenses.length === 1 ? defaultLicenses[0] : null
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
joinSwarm: async (token) => {
|
|
111
|
+
try {
|
|
112
|
+
const base64Url = token.split(".")[1];
|
|
113
|
+
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
114
|
+
const jsonPayload = decodeURIComponent(atob(base64).split("").map(function(c) {
|
|
115
|
+
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
|
|
116
|
+
}).join(""));
|
|
117
|
+
const payload = JSON.parse(jsonPayload);
|
|
118
|
+
if (!payload.tenantId || !payload.name) return false;
|
|
119
|
+
const newTarget = {
|
|
120
|
+
type: payload.type || "enterprise",
|
|
121
|
+
id: payload.tenantId,
|
|
122
|
+
name: payload.name,
|
|
123
|
+
swarmKey: payload.swarm_key,
|
|
124
|
+
websocketRelayUrl: payload.ws_url
|
|
125
|
+
};
|
|
126
|
+
const { availableLicenses } = get2();
|
|
127
|
+
if (!availableLicenses.find((l) => l.id === newTarget.id)) {
|
|
128
|
+
set2({
|
|
129
|
+
availableLicenses: [...availableLicenses, newTarget],
|
|
130
|
+
activeContext: newTarget
|
|
131
|
+
});
|
|
132
|
+
} else {
|
|
133
|
+
set2({ activeContext: newTarget });
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
} catch (e) {
|
|
137
|
+
console.error("Failed to join swarm from token", e);
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
setActiveContext: (licenseId) => {
|
|
142
|
+
const { availableLicenses } = get2();
|
|
143
|
+
const target = availableLicenses.find((l) => l.id === licenseId) || null;
|
|
144
|
+
set2({ activeContext: target });
|
|
145
|
+
},
|
|
146
|
+
setHasCompletedWelcome: (val) => {
|
|
147
|
+
set2({ hasCompletedWelcome: val });
|
|
148
|
+
},
|
|
149
|
+
setHasSeenTour: (val) => {
|
|
150
|
+
set2({ hasSeenTour: val });
|
|
151
|
+
},
|
|
152
|
+
logout: () => set2({
|
|
153
|
+
isAuthenticated: false,
|
|
154
|
+
userRole: null,
|
|
155
|
+
userName: null,
|
|
156
|
+
availableLicenses: [],
|
|
157
|
+
activeContext: null,
|
|
158
|
+
hasCompletedWelcome: false,
|
|
159
|
+
hasSeenTour: false
|
|
160
|
+
})
|
|
161
|
+
}),
|
|
162
|
+
{
|
|
163
|
+
name: "decido-auth-storage",
|
|
164
|
+
storage: (0, import_middleware.createJSONStorage)(() => secureStorage)
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
);
|
|
168
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
169
|
+
0 && (module.exports = {
|
|
170
|
+
secureStorage,
|
|
171
|
+
useAuthStore
|
|
172
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { create } from "zustand";
|
|
3
|
+
import { persist, createJSONStorage } from "zustand/middleware";
|
|
4
|
+
|
|
5
|
+
// src/secureStorage.ts
|
|
6
|
+
import { get, set, del } from "idb-keyval";
|
|
7
|
+
import { secure } from "@decido/tauri-bridge";
|
|
8
|
+
import { isTauri } from "@decido/tauri-bridge";
|
|
9
|
+
var obfuscate = (data) => {
|
|
10
|
+
if (typeof btoa === "undefined") return data;
|
|
11
|
+
return btoa(encodeURIComponent(data));
|
|
12
|
+
};
|
|
13
|
+
var deobfuscate = (data) => {
|
|
14
|
+
if (typeof atob === "undefined") return data;
|
|
15
|
+
try {
|
|
16
|
+
return decodeURIComponent(atob(data));
|
|
17
|
+
} catch {
|
|
18
|
+
return data;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var secureStorage = {
|
|
22
|
+
getItem: async (name) => {
|
|
23
|
+
try {
|
|
24
|
+
if (isTauri()) {
|
|
25
|
+
const val2 = await secure.secureVault.getItem(name);
|
|
26
|
+
if (val2 !== null) return val2;
|
|
27
|
+
}
|
|
28
|
+
const val = await get(name);
|
|
29
|
+
if (!val) return null;
|
|
30
|
+
return deobfuscate(val);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error(`[SecureStorage] Failed to get item ${name}`, err);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
setItem: async (name, value) => {
|
|
37
|
+
try {
|
|
38
|
+
if (isTauri()) {
|
|
39
|
+
await secure.secureVault.setItem(name, value);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const obfuscated = obfuscate(value);
|
|
43
|
+
await set(name, obfuscated);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error(`[SecureStorage] Failed to set item ${name}`, err);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
removeItem: async (name) => {
|
|
49
|
+
try {
|
|
50
|
+
if (isTauri()) {
|
|
51
|
+
await secure.secureVault.removeItem(name);
|
|
52
|
+
}
|
|
53
|
+
await del(name);
|
|
54
|
+
} catch (err) {
|
|
55
|
+
console.error(`[SecureStorage] Failed to remove item ${name}`, err);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// src/index.ts
|
|
61
|
+
var useAuthStore = create()(
|
|
62
|
+
persist(
|
|
63
|
+
(set2, get2) => ({
|
|
64
|
+
isAuthenticated: false,
|
|
65
|
+
userRole: null,
|
|
66
|
+
userName: null,
|
|
67
|
+
availableLicenses: [],
|
|
68
|
+
activeContext: null,
|
|
69
|
+
hasCompletedWelcome: false,
|
|
70
|
+
hasSeenTour: false,
|
|
71
|
+
login: (role, name, licenses) => {
|
|
72
|
+
const defaultLicenses = licenses || [{
|
|
73
|
+
type: "personal",
|
|
74
|
+
id: "personal",
|
|
75
|
+
name: `${name}'s Private Space`
|
|
76
|
+
}];
|
|
77
|
+
set2({
|
|
78
|
+
isAuthenticated: true,
|
|
79
|
+
userRole: role,
|
|
80
|
+
userName: name,
|
|
81
|
+
availableLicenses: defaultLicenses,
|
|
82
|
+
activeContext: defaultLicenses.length === 1 ? defaultLicenses[0] : null
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
joinSwarm: async (token) => {
|
|
86
|
+
try {
|
|
87
|
+
const base64Url = token.split(".")[1];
|
|
88
|
+
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
89
|
+
const jsonPayload = decodeURIComponent(atob(base64).split("").map(function(c) {
|
|
90
|
+
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
|
|
91
|
+
}).join(""));
|
|
92
|
+
const payload = JSON.parse(jsonPayload);
|
|
93
|
+
if (!payload.tenantId || !payload.name) return false;
|
|
94
|
+
const newTarget = {
|
|
95
|
+
type: payload.type || "enterprise",
|
|
96
|
+
id: payload.tenantId,
|
|
97
|
+
name: payload.name,
|
|
98
|
+
swarmKey: payload.swarm_key,
|
|
99
|
+
websocketRelayUrl: payload.ws_url
|
|
100
|
+
};
|
|
101
|
+
const { availableLicenses } = get2();
|
|
102
|
+
if (!availableLicenses.find((l) => l.id === newTarget.id)) {
|
|
103
|
+
set2({
|
|
104
|
+
availableLicenses: [...availableLicenses, newTarget],
|
|
105
|
+
activeContext: newTarget
|
|
106
|
+
});
|
|
107
|
+
} else {
|
|
108
|
+
set2({ activeContext: newTarget });
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.error("Failed to join swarm from token", e);
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
setActiveContext: (licenseId) => {
|
|
117
|
+
const { availableLicenses } = get2();
|
|
118
|
+
const target = availableLicenses.find((l) => l.id === licenseId) || null;
|
|
119
|
+
set2({ activeContext: target });
|
|
120
|
+
},
|
|
121
|
+
setHasCompletedWelcome: (val) => {
|
|
122
|
+
set2({ hasCompletedWelcome: val });
|
|
123
|
+
},
|
|
124
|
+
setHasSeenTour: (val) => {
|
|
125
|
+
set2({ hasSeenTour: val });
|
|
126
|
+
},
|
|
127
|
+
logout: () => set2({
|
|
128
|
+
isAuthenticated: false,
|
|
129
|
+
userRole: null,
|
|
130
|
+
userName: null,
|
|
131
|
+
availableLicenses: [],
|
|
132
|
+
activeContext: null,
|
|
133
|
+
hasCompletedWelcome: false,
|
|
134
|
+
hasSeenTour: false
|
|
135
|
+
})
|
|
136
|
+
}),
|
|
137
|
+
{
|
|
138
|
+
name: "decido-auth-storage",
|
|
139
|
+
storage: createJSONStorage(() => secureStorage)
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
);
|
|
143
|
+
export {
|
|
144
|
+
secureStorage,
|
|
145
|
+
useAuthStore
|
|
146
|
+
};
|
package/package.json
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decido/shell-auth",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"description": "Decido OS Shell Authentication & Obfuscated Persistence Core",
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
7
|
"directories": {
|
|
8
8
|
"src": "src"
|
|
9
9
|
},
|
|
10
10
|
"exports": {
|
|
11
|
-
".":
|
|
11
|
+
".": {
|
|
12
|
+
"development": "./src/index.ts",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.js",
|
|
16
|
+
"default": "./dist/index.mjs"
|
|
17
|
+
}
|
|
12
18
|
},
|
|
13
19
|
"dependencies": {
|
|
14
20
|
"idb-keyval": "^6.2.1",
|
|
15
21
|
"zustand": "^4.5.2",
|
|
16
|
-
"@decido/tauri-bridge": "4.0.
|
|
22
|
+
"@decido/tauri-bridge": "4.0.3"
|
|
17
23
|
},
|
|
18
24
|
"devDependencies": {
|
|
19
25
|
"typescript": "^5.0.0"
|
|
@@ -25,8 +31,9 @@
|
|
|
25
31
|
"files": [
|
|
26
32
|
"dist"
|
|
27
33
|
],
|
|
34
|
+
"module": "./dist/index.mjs",
|
|
28
35
|
"scripts": {
|
|
29
36
|
"lint": "eslint \"src/**/*.ts*\"",
|
|
30
|
-
"build": "tsup src/index.ts --format esm
|
|
37
|
+
"build": "tsup src/index.ts --format esm,cjs"
|
|
31
38
|
}
|
|
32
39
|
}
|
package/src/index.ts
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { create } from 'zustand';
|
|
2
|
-
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
3
|
-
import { secureStorage } from './secureStorage';
|
|
4
|
-
|
|
5
|
-
export type UserRole = 'creator' | 'admin' | 'user' | 'demo' | 'developer';
|
|
6
|
-
export type LicenseType = 'personal' | 'enterprise';
|
|
7
|
-
|
|
8
|
-
export interface LicenseTarget {
|
|
9
|
-
type: LicenseType;
|
|
10
|
-
id: string;
|
|
11
|
-
name: string;
|
|
12
|
-
enabledPlugins?: string[];
|
|
13
|
-
systemPrompt?: string;
|
|
14
|
-
swarmKey?: string;
|
|
15
|
-
websocketRelayUrl?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface AuthState {
|
|
19
|
-
isAuthenticated: boolean;
|
|
20
|
-
userRole: UserRole | null;
|
|
21
|
-
userName: string | null;
|
|
22
|
-
|
|
23
|
-
availableLicenses: LicenseTarget[];
|
|
24
|
-
activeContext: LicenseTarget | null;
|
|
25
|
-
hasCompletedWelcome: boolean;
|
|
26
|
-
hasSeenTour: boolean;
|
|
27
|
-
|
|
28
|
-
login: (role: UserRole, name: string, licenses?: LicenseTarget[]) => void;
|
|
29
|
-
joinSwarm: (token: string) => Promise<boolean>;
|
|
30
|
-
setActiveContext: (licenseId: string) => void;
|
|
31
|
-
setHasCompletedWelcome: (val: boolean) => void;
|
|
32
|
-
setHasSeenTour: (val: boolean) => void;
|
|
33
|
-
logout: () => void;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const useAuthStore = create<AuthState>()(
|
|
37
|
-
persist(
|
|
38
|
-
(set, get) => ({
|
|
39
|
-
isAuthenticated: false,
|
|
40
|
-
userRole: null,
|
|
41
|
-
userName: null,
|
|
42
|
-
availableLicenses: [],
|
|
43
|
-
activeContext: null,
|
|
44
|
-
hasCompletedWelcome: false,
|
|
45
|
-
hasSeenTour: false,
|
|
46
|
-
|
|
47
|
-
login: (role, name, licenses) => {
|
|
48
|
-
const defaultLicenses: LicenseTarget[] = licenses || [{
|
|
49
|
-
type: 'personal',
|
|
50
|
-
id: 'personal',
|
|
51
|
-
name: `${name}'s Private Space`
|
|
52
|
-
}];
|
|
53
|
-
|
|
54
|
-
set({
|
|
55
|
-
isAuthenticated: true,
|
|
56
|
-
userRole: role,
|
|
57
|
-
userName: name,
|
|
58
|
-
availableLicenses: defaultLicenses,
|
|
59
|
-
activeContext: defaultLicenses.length === 1 ? defaultLicenses[0] : null
|
|
60
|
-
});
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
joinSwarm: async (token: string) => {
|
|
64
|
-
try {
|
|
65
|
-
const base64Url = token.split('.')[1];
|
|
66
|
-
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
67
|
-
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
|
|
68
|
-
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
|
69
|
-
}).join(''));
|
|
70
|
-
|
|
71
|
-
const payload = JSON.parse(jsonPayload);
|
|
72
|
-
|
|
73
|
-
if (!payload.tenantId || !payload.name) return false;
|
|
74
|
-
|
|
75
|
-
const newTarget: LicenseTarget = {
|
|
76
|
-
type: payload.type || 'enterprise',
|
|
77
|
-
id: payload.tenantId,
|
|
78
|
-
name: payload.name,
|
|
79
|
-
swarmKey: payload.swarm_key,
|
|
80
|
-
websocketRelayUrl: payload.ws_url
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const { availableLicenses } = get();
|
|
84
|
-
if (!availableLicenses.find(l => l.id === newTarget.id)) {
|
|
85
|
-
set({
|
|
86
|
-
availableLicenses: [...availableLicenses, newTarget],
|
|
87
|
-
activeContext: newTarget
|
|
88
|
-
});
|
|
89
|
-
} else {
|
|
90
|
-
set({ activeContext: newTarget });
|
|
91
|
-
}
|
|
92
|
-
return true;
|
|
93
|
-
} catch (e) {
|
|
94
|
-
console.error("Failed to join swarm from token", e);
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
setActiveContext: (licenseId: string) => {
|
|
100
|
-
const { availableLicenses } = get();
|
|
101
|
-
const target = availableLicenses.find(l => l.id === licenseId) || null;
|
|
102
|
-
set({ activeContext: target });
|
|
103
|
-
},
|
|
104
|
-
|
|
105
|
-
setHasCompletedWelcome: (val: boolean) => {
|
|
106
|
-
set({ hasCompletedWelcome: val });
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
setHasSeenTour: (val: boolean) => {
|
|
110
|
-
set({ hasSeenTour: val });
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
logout: () => set({
|
|
114
|
-
isAuthenticated: false,
|
|
115
|
-
userRole: null,
|
|
116
|
-
userName: null,
|
|
117
|
-
availableLicenses: [],
|
|
118
|
-
activeContext: null,
|
|
119
|
-
hasCompletedWelcome: false,
|
|
120
|
-
hasSeenTour: false
|
|
121
|
-
}),
|
|
122
|
-
}),
|
|
123
|
-
{
|
|
124
|
-
name: 'decido-auth-storage',
|
|
125
|
-
storage: createJSONStorage(() => secureStorage)
|
|
126
|
-
}
|
|
127
|
-
)
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
// Re-export secureStorage helper just in case it's needed externally
|
|
131
|
-
export * from './secureStorage';
|