@squiz/resource-browser 3.3.10 → 3.3.11
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/CHANGELOG.md +6 -0
- package/lib/Hooks/useAuth.d.ts +1 -0
- package/lib/Hooks/useAuth.js +20 -0
- package/lib/Plugin/Plugin.js +2 -1
- package/lib/ResourceBrowserContext/AuthProvider.d.ts +1 -0
- package/lib/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/Hooks/useAuth.spec.tsx +45 -2
- package/src/Hooks/useAuth.ts +23 -0
- package/src/Plugin/Plugin.spec.tsx +17 -0
- package/src/Plugin/Plugin.tsx +3 -1
- package/src/ResourceBrowserContext/AuthProvider.spec.tsx +4 -1
- package/src/ResourceBrowserContext/AuthProvider.tsx +1 -0
- package/src/types.ts +3 -0
package/CHANGELOG.md
CHANGED
package/lib/Hooks/useAuth.d.ts
CHANGED
package/lib/Hooks/useAuth.js
CHANGED
|
@@ -61,6 +61,11 @@ const useAuth = (authConfig) => {
|
|
|
61
61
|
setIsAuthenticated(!!token);
|
|
62
62
|
};
|
|
63
63
|
(0, react_1.useEffect)(() => {
|
|
64
|
+
// Don't run internal processes if we are always using the resource request proxy
|
|
65
|
+
if (authConfig?.alwaysUseResourceRequestProxy) {
|
|
66
|
+
// Consistent return value for cleanup function
|
|
67
|
+
return () => { };
|
|
68
|
+
}
|
|
64
69
|
const handleTabChange = () => {
|
|
65
70
|
if (!document.hidden) {
|
|
66
71
|
syncAuthState();
|
|
@@ -75,15 +80,30 @@ const useAuth = (authConfig) => {
|
|
|
75
80
|
};
|
|
76
81
|
}, []);
|
|
77
82
|
(0, react_1.useEffect)(() => {
|
|
83
|
+
// Don't run internal processes if we are always using the resource request proxy
|
|
84
|
+
if (authConfig?.alwaysUseResourceRequestProxy) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
78
87
|
refreshAccessToken().catch(() => {
|
|
79
88
|
setIsAuthenticated(false);
|
|
80
89
|
});
|
|
81
90
|
}, [authConfig, refreshAccessToken]);
|
|
91
|
+
// Return some dummy data if we are always using the resource request proxy
|
|
92
|
+
if (authConfig?.alwaysUseResourceRequestProxy) {
|
|
93
|
+
return {
|
|
94
|
+
authToken: null,
|
|
95
|
+
isAuthenticated: true,
|
|
96
|
+
login: () => { },
|
|
97
|
+
refreshAccessToken: () => Promise.resolve(''),
|
|
98
|
+
alwaysUseResourceRequestProxy: true,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
82
101
|
return {
|
|
83
102
|
authToken,
|
|
84
103
|
isAuthenticated,
|
|
85
104
|
login: handleLogin,
|
|
86
105
|
refreshAccessToken,
|
|
106
|
+
alwaysUseResourceRequestProxy: false,
|
|
87
107
|
};
|
|
88
108
|
};
|
|
89
109
|
exports.useAuth = useAuth;
|
package/lib/Plugin/Plugin.js
CHANGED
|
@@ -31,7 +31,8 @@ const AuthProvider_1 = require("../ResourceBrowserContext/AuthProvider");
|
|
|
31
31
|
exports.PluginRender = (0, react_1.forwardRef)(({ render, inline, inlineType, ...props }, forwardRef) => {
|
|
32
32
|
if (!render)
|
|
33
33
|
return react_1.default.createElement(react_1.default.Fragment, null);
|
|
34
|
-
const requiresAuth = Boolean(props.source?.configuration?.authUrl)
|
|
34
|
+
const requiresAuth = Boolean(props.source?.configuration?.authUrl) ||
|
|
35
|
+
Boolean(props.source?.configuration?.alwaysUseResourceRequestProxy);
|
|
35
36
|
const content = inline && inlineType ? (react_1.default.createElement(ResourceBrowserInlineButton_1.ResourceBrowserInlineButton, { ref: forwardRef, inlineType: inlineType, ...props })) : (react_1.default.createElement(ResourceBrowserInput_1.ResourceBrowserInput, { ...props }));
|
|
36
37
|
return requiresAuth ? react_1.default.createElement(AuthProvider_1.AuthProvider, { authConfig: props.source }, content) : content;
|
|
37
38
|
});
|
|
@@ -5,6 +5,7 @@ interface AuthContextProps {
|
|
|
5
5
|
isAuthenticated: boolean;
|
|
6
6
|
login: () => void;
|
|
7
7
|
refreshAccessToken: () => Promise<any>;
|
|
8
|
+
alwaysUseResourceRequestProxy: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare const AuthContext: React.Context<AuthContextProps | undefined>;
|
|
10
11
|
export declare const useAuthContext: () => AuthContextProps;
|
package/lib/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -29,9 +29,9 @@ describe('useAuth', () => {
|
|
|
29
29
|
await waitFor(() => {
|
|
30
30
|
expect(result.current.authToken).toBe('initialAuthToken');
|
|
31
31
|
expect(result.current.isAuthenticated).toBe(true);
|
|
32
|
+
expect(result.current.alwaysUseResourceRequestProxy).toBe(false);
|
|
32
33
|
});
|
|
33
34
|
});
|
|
34
|
-
|
|
35
35
|
it('should do nothing if missing crucial props', async () => {
|
|
36
36
|
const authConfigMissingProps = {
|
|
37
37
|
clientId: 'example-client-id',
|
|
@@ -285,7 +285,7 @@ describe('useAuth', () => {
|
|
|
285
285
|
});
|
|
286
286
|
|
|
287
287
|
it('should throw an error when getCookieValue throws unexpectedly', () => {
|
|
288
|
-
jest.spyOn(authUtils, 'getCookieValue').mockImplementation(() => {
|
|
288
|
+
const getCookieValueSpy = jest.spyOn(authUtils, 'getCookieValue').mockImplementation(() => {
|
|
289
289
|
throw new Error('Unexpected error');
|
|
290
290
|
});
|
|
291
291
|
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
@@ -293,5 +293,48 @@ describe('useAuth', () => {
|
|
|
293
293
|
expect(() => renderHook(() => useAuth(authConfig))).toThrow('Unexpected error');
|
|
294
294
|
|
|
295
295
|
consoleSpy.mockRestore();
|
|
296
|
+
getCookieValueSpy.mockRestore();
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe('alwaysUseResourceRequestProxy', () => {
|
|
300
|
+
const authConfigAlwaysUseResourceRequestProxy = { ...authConfig, alwaysUseResourceRequestProxy: true };
|
|
301
|
+
it('should initialize with alwaysUseResourceRequestProxy true', async () => {
|
|
302
|
+
const { result } = renderHook(() => useAuth(authConfigAlwaysUseResourceRequestProxy));
|
|
303
|
+
|
|
304
|
+
await waitFor(() => {
|
|
305
|
+
expect(result.current.authToken).toBe(null);
|
|
306
|
+
expect(result.current.isAuthenticated).toBe(true);
|
|
307
|
+
expect(result.current.alwaysUseResourceRequestProxy).toBe(true);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Check that refreshAccessToken is not called when authConfig changes
|
|
311
|
+
// Set up a spy and test that refreshAccessToken is not called when authConfig changes
|
|
312
|
+
const refreshAccessTokenSpy = jest.spyOn(authUtils, 'refreshAccessToken');
|
|
313
|
+
|
|
314
|
+
// Change authConfig and rerender
|
|
315
|
+
const newConfig = { ...authConfigAlwaysUseResourceRequestProxy, clientId: 'changed-client-id' };
|
|
316
|
+
const { rerender } = renderHook((props) => useAuth(props), { initialProps: authConfigAlwaysUseResourceRequestProxy });
|
|
317
|
+
rerender(newConfig);
|
|
318
|
+
|
|
319
|
+
// refreshAccessToken should not be called
|
|
320
|
+
expect(refreshAccessTokenSpy).not.toHaveBeenCalled();
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it('should not attach event listeners when alwaysUseResourceRequestProxy is true', async () => {
|
|
324
|
+
mockGetCookieValue.mockReturnValueOnce(null);
|
|
325
|
+
const { result } = renderHook(() => useAuth(authConfigAlwaysUseResourceRequestProxy));
|
|
326
|
+
|
|
327
|
+
mockGetCookieValue.mockReturnValue('visibleAuthToken');
|
|
328
|
+
|
|
329
|
+
Object.defineProperty(document, 'hidden', { configurable: true, value: false });
|
|
330
|
+
|
|
331
|
+
act(() => {
|
|
332
|
+
document.dispatchEvent(new Event('visibilitychange'));
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
await waitFor(() => {
|
|
336
|
+
expect(result.current.authToken).toBe(null);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
296
339
|
});
|
|
297
340
|
});
|
package/src/Hooks/useAuth.ts
CHANGED
|
@@ -65,6 +65,12 @@ export const useAuth = (authConfig: AuthenticationConfiguration | undefined) =>
|
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
useEffect(() => {
|
|
68
|
+
// Don't run internal processes if we are always using the resource request proxy
|
|
69
|
+
if (authConfig?.alwaysUseResourceRequestProxy) {
|
|
70
|
+
// Consistent return value for cleanup function
|
|
71
|
+
return () => {};
|
|
72
|
+
}
|
|
73
|
+
|
|
68
74
|
const handleTabChange = () => {
|
|
69
75
|
if (!document.hidden) {
|
|
70
76
|
syncAuthState();
|
|
@@ -82,15 +88,32 @@ export const useAuth = (authConfig: AuthenticationConfiguration | undefined) =>
|
|
|
82
88
|
}, []);
|
|
83
89
|
|
|
84
90
|
useEffect(() => {
|
|
91
|
+
// Don't run internal processes if we are always using the resource request proxy
|
|
92
|
+
if (authConfig?.alwaysUseResourceRequestProxy) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
85
96
|
refreshAccessToken().catch(() => {
|
|
86
97
|
setIsAuthenticated(false);
|
|
87
98
|
});
|
|
88
99
|
}, [authConfig, refreshAccessToken]);
|
|
89
100
|
|
|
101
|
+
// Return some dummy data if we are always using the resource request proxy
|
|
102
|
+
if (authConfig?.alwaysUseResourceRequestProxy) {
|
|
103
|
+
return {
|
|
104
|
+
authToken: null,
|
|
105
|
+
isAuthenticated: true,
|
|
106
|
+
login: () => {},
|
|
107
|
+
refreshAccessToken: () => Promise.resolve(''),
|
|
108
|
+
alwaysUseResourceRequestProxy: true,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
90
112
|
return {
|
|
91
113
|
authToken,
|
|
92
114
|
isAuthenticated,
|
|
93
115
|
login: handleLogin,
|
|
94
116
|
refreshAccessToken,
|
|
117
|
+
alwaysUseResourceRequestProxy: false,
|
|
95
118
|
};
|
|
96
119
|
};
|
|
@@ -81,4 +81,21 @@ describe('Plugin', () => {
|
|
|
81
81
|
expect(AuthContext.AuthProvider).toHaveBeenCalledWith({ authConfig: sourceWithAuth, children: expect.anything() }, {});
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
|
+
|
|
85
|
+
it('Wraps content in AuthProvider when alwaysUseResourceRequestProxy is true', async () => {
|
|
86
|
+
const sourceWithAuth = {
|
|
87
|
+
id: '123',
|
|
88
|
+
type: 'dam' as ResourceBrowserPluginType,
|
|
89
|
+
configuration: {
|
|
90
|
+
alwaysUseResourceRequestProxy: true,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const props = { ...baseProps, source: sourceWithAuth };
|
|
95
|
+
render(<PluginRender render={true} inline={false} {...props} />);
|
|
96
|
+
|
|
97
|
+
await waitFor(() => {
|
|
98
|
+
expect(AuthContext.AuthProvider).toHaveBeenCalledWith({ authConfig: sourceWithAuth, children: expect.anything() }, {});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
84
101
|
});
|
package/src/Plugin/Plugin.tsx
CHANGED
|
@@ -22,7 +22,9 @@ export type PluginRenderType = ResourceBrowserInputProps & {
|
|
|
22
22
|
export const PluginRender = forwardRef<HTMLButtonElement, PluginRenderType>(({ render, inline, inlineType, ...props }, forwardRef) => {
|
|
23
23
|
if (!render) return <></>;
|
|
24
24
|
|
|
25
|
-
const requiresAuth =
|
|
25
|
+
const requiresAuth =
|
|
26
|
+
Boolean((props.source as ResourceBrowserSourceWithConfig)?.configuration?.authUrl) ||
|
|
27
|
+
Boolean((props.source as ResourceBrowserSourceWithConfig)?.configuration?.alwaysUseResourceRequestProxy);
|
|
26
28
|
|
|
27
29
|
const content =
|
|
28
30
|
inline && inlineType ? (
|
|
@@ -27,6 +27,7 @@ describe('AuthContext', () => {
|
|
|
27
27
|
isAuthenticated: true,
|
|
28
28
|
login: jest.fn(),
|
|
29
29
|
refreshAccessToken: jest.fn(),
|
|
30
|
+
alwaysUseResourceRequestProxy: false,
|
|
30
31
|
};
|
|
31
32
|
|
|
32
33
|
beforeEach(() => {
|
|
@@ -36,12 +37,13 @@ describe('AuthContext', () => {
|
|
|
36
37
|
|
|
37
38
|
it('should provide auth state and functions to consumers', async () => {
|
|
38
39
|
const TestComponent = () => {
|
|
39
|
-
const { authToken, isAuthenticated, login } = useAuthContext();
|
|
40
|
+
const { authToken, isAuthenticated, login, alwaysUseResourceRequestProxy } = useAuthContext();
|
|
40
41
|
return (
|
|
41
42
|
<div>
|
|
42
43
|
<span>{`Token: ${authToken}`}</span>
|
|
43
44
|
<span>{`Authenticated: ${isAuthenticated}`}</span>
|
|
44
45
|
<button onClick={login}>Login</button>
|
|
46
|
+
<span>{`Always use resource request proxy: ${alwaysUseResourceRequestProxy}`}</span>
|
|
45
47
|
</div>
|
|
46
48
|
);
|
|
47
49
|
};
|
|
@@ -54,6 +56,7 @@ describe('AuthContext', () => {
|
|
|
54
56
|
|
|
55
57
|
expect(screen.getByText(/Token: testAuthToken/)).toBeInTheDocument();
|
|
56
58
|
expect(screen.getByText(/Authenticated: true/)).toBeInTheDocument();
|
|
59
|
+
expect(screen.getByText(/Always use resource request proxy: false/)).toBeInTheDocument();
|
|
57
60
|
|
|
58
61
|
fireEvent.click(screen.getByText('Login'));
|
|
59
62
|
|
package/src/types.ts
CHANGED