@jolibox/sdk 1.1.13-beta.2 → 1.1.13-beta.4

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.
@@ -1,36 +0,0 @@
1
- import { createStorageIsolation } from './localstorage-protector';
2
- import { getOriginalLocalStorage } from '../local-storage';
3
-
4
- createStorageIsolation({
5
- namespace: 'jolibox-sdk-test'
6
- });
7
-
8
- describe('getOriginalLocalStorage', () => {
9
- it('should return localStorage object', () => {
10
- const originalStorage = getOriginalLocalStorage();
11
-
12
- expect(originalStorage).toBeDefined();
13
- expect(typeof originalStorage.getItem).toBe('function');
14
- expect(typeof originalStorage.setItem).toBe('function');
15
- expect(typeof originalStorage.removeItem).toBe('function');
16
- });
17
-
18
- it('should be able to store and get data', () => {
19
- const originalStorage = getOriginalLocalStorage();
20
- const testKey = '__test_key__';
21
- const testValue = 'test-value';
22
-
23
- originalStorage.removeItem(testKey);
24
-
25
- originalStorage.setItem(testKey, testValue);
26
-
27
- // 验证数据是否正确存储
28
- expect(originalStorage.getItem(testKey)).toBe(testValue);
29
- expect(originalStorage.getItem('jolibox-sdk-test:__test_key__')).toBeNull();
30
-
31
- // 清理测试数据
32
- originalStorage.removeItem(testKey);
33
- expect(originalStorage.getItem(testKey)).toBeNull();
34
- expect(originalStorage.getItem('jolibox-sdk-test:__test_key__')).toBeNull();
35
- });
36
- });
@@ -1,191 +0,0 @@
1
- type StorageIsolationOptions = {
2
- namespace?: string;
3
- debug?: boolean;
4
- };
5
-
6
- declare global {
7
- interface Window {
8
- __joliboxLocalStorage__: typeof window.localStorage;
9
- }
10
- }
11
-
12
- export function createStorageIsolation(options: StorageIsolationOptions = {}) {
13
- const namespace = options.namespace || getJoliMpId();
14
- const debug = options.debug || true;
15
- const observedFrames = new WeakSet<HTMLIFrameElement>();
16
-
17
- function getJoliMpId() {
18
- const urlParams = new URLSearchParams(window.location.search);
19
- return urlParams.get('mpId') ?? urlParams.get('appId') ?? urlParams.get('gameId') ?? '';
20
- }
21
-
22
- function _log(message: string) {
23
- if (debug) {
24
- console.log(`[StorageIsolation] ${message}`);
25
- }
26
- }
27
-
28
- function createIsolatedStorage() {
29
- const originalStorage = window.localStorage;
30
-
31
- return {
32
- setItem(key: string, value: string) {
33
- const namespacedKey = key.startsWith(`${namespace}:`) ? key : `${namespace}:${key}`;
34
- originalStorage.setItem(namespacedKey, value);
35
- },
36
- getItem(key: string) {
37
- const namespacedKey = key.startsWith(`${namespace}:`) ? key : `${namespace}:${key}`;
38
- let value = originalStorage.getItem(namespacedKey);
39
- if (value === null) {
40
- // 如果命名空间不存在,则尝试直接获取原始键
41
- const originalKey = key.startsWith(`${namespace}:`) ? key.slice(namespace.length + 1) : key;
42
- value = originalStorage.getItem(originalKey);
43
- }
44
- return value;
45
- },
46
- removeItem(key: string) {
47
- const namespacedKey = key.startsWith(`${namespace}:`) ? key : `${namespace}:${key}`;
48
- originalStorage.removeItem(namespacedKey);
49
- },
50
- clear() {
51
- const keys = Object.keys(originalStorage);
52
- for (const key of keys) {
53
- if (key.startsWith(`${namespace}:`)) {
54
- originalStorage.removeItem(key);
55
- }
56
- }
57
- },
58
- key(index: number) {
59
- const keys = Object.keys(originalStorage)
60
- .filter((key) => key.startsWith(`${namespace}:`))
61
- .map((key) => key.slice(namespace.length + 1));
62
- return keys[index] || null;
63
- },
64
- get length() {
65
- return Object.keys(originalStorage).filter((key) => key.startsWith(`${namespace}:`)).length;
66
- }
67
- };
68
- }
69
-
70
- function injectIsolatedStorage(
71
- frameWindow: Window,
72
- isolatedStorage: ReturnType<typeof createIsolatedStorage>
73
- ) {
74
- try {
75
- const originalStorage = frameWindow.localStorage;
76
- window.__joliboxLocalStorage__ = originalStorage;
77
-
78
- type StorageProp = keyof typeof isolatedStorage;
79
- const storageProxy = new Proxy(originalStorage, {
80
- get: (target, prop: StorageProp) => {
81
- if (prop in isolatedStorage) {
82
- return isolatedStorage[prop];
83
- }
84
- if (typeof target[prop] === 'function') {
85
- return target[prop].bind(target);
86
- }
87
- return target[prop];
88
- },
89
- set: (target, prop: StorageProp, value) => {
90
- if (prop === 'length') {
91
- return true;
92
- }
93
- if (prop in isolatedStorage) {
94
- isolatedStorage[prop] = value;
95
- return true;
96
- }
97
- target[prop] = value;
98
- return true;
99
- }
100
- });
101
-
102
- Object.defineProperty(frameWindow, 'localStorage', {
103
- get: () => storageProxy,
104
- configurable: true
105
- });
106
- } catch (e) {
107
- _log(`Failed to inject storage proxy: ${e}`);
108
- }
109
- }
110
-
111
- function injectIsolation(frame: HTMLIFrameElement) {
112
- try {
113
- const frameWindow = frame.contentWindow;
114
- const frameDocument = frame.contentDocument;
115
-
116
- if (!frameWindow || !frameDocument) {
117
- _log('Cannot access frame content - likely due to same-origin policy');
118
- return;
119
- }
120
-
121
- const isolatedStorage = createIsolatedStorage();
122
- injectIsolatedStorage(frameWindow, isolatedStorage);
123
- _log(`Successfully isolated storage for frame: ${frame.src}`);
124
- } catch (e) {
125
- _log(`Injection failed: ${e}`);
126
- }
127
- }
128
-
129
- function isolateFrame(frame: HTMLIFrameElement) {
130
- if (observedFrames.has(frame)) {
131
- return;
132
- }
133
-
134
- try {
135
- frame.addEventListener('load', () => {
136
- injectIsolation(frame);
137
- });
138
- if (frame.contentDocument && frame.contentDocument.readyState === 'complete') {
139
- injectIsolation(frame);
140
- }
141
-
142
- observedFrames.add(frame);
143
- } catch (e) {
144
- _log(`Failed to isolate frame: ${e}`);
145
- }
146
- }
147
-
148
- function handleExistingFrames() {
149
- document.querySelectorAll('iframe').forEach((frame) => {
150
- injectIsolation(frame);
151
- });
152
- }
153
-
154
- function startObserving() {
155
- handleExistingFrames();
156
-
157
- const observer = new MutationObserver((mutations) => {
158
- mutations.forEach((mutation) => {
159
- mutation.addedNodes.forEach((node) => {
160
- if (node instanceof HTMLIFrameElement) {
161
- isolateFrame(node);
162
- }
163
- });
164
- });
165
- });
166
-
167
- observer.observe(document.documentElement, {
168
- childList: true,
169
- subtree: true
170
- });
171
-
172
- _log('Started observing iframe creation');
173
- }
174
-
175
- function isolateWindowStorage() {
176
- const isolatedStorage = createIsolatedStorage();
177
- injectIsolatedStorage(window, isolatedStorage);
178
- }
179
-
180
- // Initialize
181
- startObserving();
182
- isolateWindowStorage();
183
-
184
- // Return public API if needed
185
- return {
186
- isolateFrame,
187
- isolateWindowStorage
188
- };
189
- }
190
-
191
- createStorageIsolation();
@@ -1,33 +0,0 @@
1
- export function getOriginalLocalStorage(): Storage {
2
- try {
3
- if (window.__joliboxLocalStorage__) {
4
- return window.__joliboxLocalStorage__;
5
- }
6
-
7
- let originalDescriptor = Object.getOwnPropertyDescriptor(window, 'localStorage');
8
- if (originalDescriptor && originalDescriptor.get) {
9
- const originalLocalStorage = originalDescriptor.get.call(window);
10
- window.__joliboxLocalStorage__ = originalLocalStorage;
11
- return originalLocalStorage;
12
- }
13
-
14
- originalDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(window), 'localStorage');
15
- if (originalDescriptor && originalDescriptor.get) {
16
- const originalLocalStorage = originalDescriptor.get.call(window);
17
- return originalLocalStorage;
18
- }
19
-
20
- const windowProto = Window.prototype;
21
- const protoDescriptor = Object.getOwnPropertyDescriptor(windowProto, 'localStorage');
22
- if (protoDescriptor && protoDescriptor.get) {
23
- const protoLocalStorage = protoDescriptor.get.call(window);
24
- window.__joliboxLocalStorage__ = protoLocalStorage;
25
- return protoLocalStorage;
26
- }
27
-
28
- return localStorage;
29
- } catch (e) {
30
- console.warn('Failed to get original localStorage, fallback to default implementation', e);
31
- return localStorage;
32
- }
33
- }