@oxyhq/services 13.1.0 → 13.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/lib/commonjs/ui/components/SettingsIcon.js.map +1 -1
- package/lib/commonjs/ui/components/fileManagement/FileViewer.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +17 -45
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/utils/activeAuthuser.js +14 -35
- package/lib/commonjs/ui/utils/activeAuthuser.js.map +1 -1
- package/lib/module/ui/components/SettingsIcon.js.map +1 -1
- package/lib/module/ui/components/fileManagement/FileViewer.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +17 -45
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/utils/activeAuthuser.js +14 -35
- package/lib/module/ui/utils/activeAuthuser.js.map +1 -1
- package/lib/typescript/commonjs/ui/components/SettingsIcon.d.ts +2 -1
- package/lib/typescript/commonjs/ui/components/SettingsIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/payment/types.d.ts +3 -1
- package/lib/typescript/commonjs/ui/components/payment/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/activeAuthuser.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/SettingsIcon.d.ts +2 -1
- package/lib/typescript/module/ui/components/SettingsIcon.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/types.d.ts +3 -1
- package/lib/typescript/module/ui/components/payment/types.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/activeAuthuser.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/ui/components/ProfileMenu.tsx +1 -1
- package/src/ui/components/SettingsIcon.tsx +2 -2
- package/src/ui/components/fileManagement/FileViewer.tsx +1 -1
- package/src/ui/components/payment/types.ts +3 -1
- package/src/ui/context/OxyContext.tsx +17 -45
- package/src/ui/screens/FeedbackScreen.tsx +3 -3
- package/src/ui/utils/activeAuthuser.ts +14 -34
- package/src/ui/utils/__tests__/activeAuthuser.test.ts +0 -75
|
@@ -30,22 +30,8 @@ import {
|
|
|
30
30
|
|
|
31
31
|
const ACTIVE_AUTHUSER_KEY = 'oxy_active_authuser';
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* unavailable. The PROPERTY ACCESS itself (`window.localStorage`) can throw a
|
|
36
|
-
* `SecurityError` synchronously in opaque-origin / sandboxed iframes or when
|
|
37
|
-
* storage is disabled — even `typeof window.localStorage` evaluates the getter
|
|
38
|
-
* and throws. Every read/write in this module routes through here so the getter
|
|
39
|
-
* throw is caught once, at the source, and callers stay clean. Returns `null`
|
|
40
|
-
* off-web and on any access failure (fail safe).
|
|
41
|
-
*/
|
|
42
|
-
function getLocalStorage(): Storage | null {
|
|
43
|
-
if (typeof window === 'undefined') return null;
|
|
44
|
-
try {
|
|
45
|
-
return window.localStorage ?? null;
|
|
46
|
-
} catch {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
33
|
+
function hasLocalStorage(): boolean {
|
|
34
|
+
return typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';
|
|
49
35
|
}
|
|
50
36
|
|
|
51
37
|
function getSessionStorage(): Storage | null {
|
|
@@ -65,12 +51,11 @@ function getSessionStorage(): Storage | null {
|
|
|
65
51
|
* fall back to deterministic selection (lowest authuser).
|
|
66
52
|
*/
|
|
67
53
|
export function readActiveAuthuser(): number | null {
|
|
68
|
-
|
|
69
|
-
if (!storage) {
|
|
54
|
+
if (!hasLocalStorage()) {
|
|
70
55
|
return null;
|
|
71
56
|
}
|
|
72
57
|
try {
|
|
73
|
-
const raw =
|
|
58
|
+
const raw = window.localStorage.getItem(ACTIVE_AUTHUSER_KEY);
|
|
74
59
|
if (raw === null) return null;
|
|
75
60
|
const parsed = Number.parseInt(raw, 10);
|
|
76
61
|
if (!Number.isFinite(parsed) || parsed < 0) return null;
|
|
@@ -86,11 +71,10 @@ export function readActiveAuthuser(): number | null {
|
|
|
86
71
|
* this succeeding — it is best-effort UX persistence, not authoritative.
|
|
87
72
|
*/
|
|
88
73
|
export function writeActiveAuthuser(authuser: number): void {
|
|
74
|
+
if (!hasLocalStorage()) return;
|
|
89
75
|
if (!Number.isFinite(authuser) || authuser < 0) return;
|
|
90
|
-
const storage = getLocalStorage();
|
|
91
|
-
if (!storage) return;
|
|
92
76
|
try {
|
|
93
|
-
|
|
77
|
+
window.localStorage.setItem(ACTIVE_AUTHUSER_KEY, String(authuser));
|
|
94
78
|
} catch {
|
|
95
79
|
// Best-effort persistence; swallow QuotaExceededError / SecurityError.
|
|
96
80
|
}
|
|
@@ -102,10 +86,9 @@ export function writeActiveAuthuser(authuser: number): void {
|
|
|
102
86
|
* cleared slot.
|
|
103
87
|
*/
|
|
104
88
|
export function clearActiveAuthuser(): void {
|
|
105
|
-
|
|
106
|
-
if (!storage) return;
|
|
89
|
+
if (!hasLocalStorage()) return;
|
|
107
90
|
try {
|
|
108
|
-
|
|
91
|
+
window.localStorage.removeItem(ACTIVE_AUTHUSER_KEY);
|
|
109
92
|
} catch {
|
|
110
93
|
// Best-effort.
|
|
111
94
|
}
|
|
@@ -120,10 +103,9 @@ export function clearActiveAuthuser(): void {
|
|
|
120
103
|
* failure (best-effort).
|
|
121
104
|
*/
|
|
122
105
|
export function markSignedOut(): void {
|
|
123
|
-
|
|
124
|
-
if (!storage) return;
|
|
106
|
+
if (!hasLocalStorage()) return;
|
|
125
107
|
try {
|
|
126
|
-
|
|
108
|
+
window.localStorage.setItem(ssoSignedOutKey(window.location.origin), '1');
|
|
127
109
|
} catch {
|
|
128
110
|
// Best-effort; swallow QuotaExceededError / SecurityError (private mode).
|
|
129
111
|
}
|
|
@@ -136,10 +118,9 @@ export function markSignedOut(): void {
|
|
|
136
118
|
* state. No-ops on native / storage failure.
|
|
137
119
|
*/
|
|
138
120
|
export function clearSignedOut(): void {
|
|
139
|
-
|
|
140
|
-
if (!storage) return;
|
|
121
|
+
if (!hasLocalStorage()) return;
|
|
141
122
|
try {
|
|
142
|
-
|
|
123
|
+
window.localStorage.removeItem(ssoSignedOutKey(window.location.origin));
|
|
143
124
|
} catch {
|
|
144
125
|
// Best-effort.
|
|
145
126
|
}
|
|
@@ -153,9 +134,8 @@ export function clearSignedOut(): void {
|
|
|
153
134
|
* `fedcm-silent` and `silent-iframe` cold-boot steps.
|
|
154
135
|
*/
|
|
155
136
|
export function isSilentRestoreSuppressed(): boolean {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return silentRestoreSuppressed(storage, window.location.origin);
|
|
137
|
+
if (!hasLocalStorage()) return false;
|
|
138
|
+
return silentRestoreSuppressed(window.localStorage, window.location.origin);
|
|
159
139
|
}
|
|
160
140
|
|
|
161
141
|
/**
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fail-safe guarantees for the web `activeAuthuser` storage helpers.
|
|
3
|
-
*
|
|
4
|
-
* The PROPERTY ACCESS `window.localStorage` can throw a `SecurityError`
|
|
5
|
-
* synchronously in opaque-origin / sandboxed iframes or when storage is
|
|
6
|
-
* disabled — not just `getItem`/`setItem`. These helpers run during cold boot
|
|
7
|
-
* (and feed render-phase gate values in the providers), so they MUST never
|
|
8
|
-
* propagate that throw: reads fail safe to a benign default and writes no-op.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
readActiveAuthuser,
|
|
13
|
-
writeActiveAuthuser,
|
|
14
|
-
clearActiveAuthuser,
|
|
15
|
-
markSignedOut,
|
|
16
|
-
clearSignedOut,
|
|
17
|
-
isSilentRestoreSuppressed,
|
|
18
|
-
} from '../activeAuthuser';
|
|
19
|
-
|
|
20
|
-
describe('activeAuthuser helpers — localStorage fail-safe', () => {
|
|
21
|
-
const realDescriptor = Object.getOwnPropertyDescriptor(window, 'localStorage');
|
|
22
|
-
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
if (realDescriptor) {
|
|
25
|
-
Object.defineProperty(window, 'localStorage', realDescriptor);
|
|
26
|
-
}
|
|
27
|
-
window.localStorage?.clear?.();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
/** Replace the `localStorage` accessor so reading the property throws. */
|
|
31
|
-
function makeLocalStorageGetterThrow(): void {
|
|
32
|
-
Object.defineProperty(window, 'localStorage', {
|
|
33
|
-
configurable: true,
|
|
34
|
-
get() {
|
|
35
|
-
throw new DOMException('denied', 'SecurityError');
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
it('readActiveAuthuser returns null (never throws) when the getter throws', () => {
|
|
41
|
-
makeLocalStorageGetterThrow();
|
|
42
|
-
expect(() => readActiveAuthuser()).not.toThrow();
|
|
43
|
-
expect(readActiveAuthuser()).toBeNull();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('isSilentRestoreSuppressed returns false (never throws) when the getter throws', () => {
|
|
47
|
-
makeLocalStorageGetterThrow();
|
|
48
|
-
expect(() => isSilentRestoreSuppressed()).not.toThrow();
|
|
49
|
-
expect(isSilentRestoreSuppressed()).toBe(false);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('writeActiveAuthuser / clearActiveAuthuser / markSignedOut / clearSignedOut no-op when the getter throws', () => {
|
|
53
|
-
makeLocalStorageGetterThrow();
|
|
54
|
-
expect(() => {
|
|
55
|
-
writeActiveAuthuser(2);
|
|
56
|
-
clearActiveAuthuser();
|
|
57
|
-
markSignedOut();
|
|
58
|
-
clearSignedOut();
|
|
59
|
-
}).not.toThrow();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('round-trips normally when storage works (zero behavior change)', () => {
|
|
63
|
-
writeActiveAuthuser(3);
|
|
64
|
-
expect(readActiveAuthuser()).toBe(3);
|
|
65
|
-
|
|
66
|
-
expect(isSilentRestoreSuppressed()).toBe(false);
|
|
67
|
-
markSignedOut();
|
|
68
|
-
expect(isSilentRestoreSuppressed()).toBe(true);
|
|
69
|
-
clearSignedOut();
|
|
70
|
-
expect(isSilentRestoreSuppressed()).toBe(false);
|
|
71
|
-
|
|
72
|
-
clearActiveAuthuser();
|
|
73
|
-
expect(readActiveAuthuser()).toBeNull();
|
|
74
|
-
});
|
|
75
|
-
});
|