@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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # Change Log
2
2
 
3
+ ## 3.3.11
4
+
5
+ ### Patch Changes
6
+
7
+ - 6c4d5b3: Support for proxying all dam requests
8
+
3
9
  ## 3.3.10
4
10
 
5
11
  ### Patch Changes
@@ -4,4 +4,5 @@ export declare const useAuth: (authConfig: AuthenticationConfiguration | undefin
4
4
  isAuthenticated: boolean;
5
5
  login: () => void;
6
6
  refreshAccessToken: () => Promise<string>;
7
+ alwaysUseResourceRequestProxy: boolean;
7
8
  };
@@ -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;
@@ -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
@@ -8,6 +8,7 @@ export type AuthenticationConfiguration = {
8
8
  redirectUrl: string;
9
9
  clientId: string;
10
10
  scope: string;
11
+ alwaysUseResourceRequestProxy?: boolean;
11
12
  };
12
13
  export interface ResourceBrowserSource {
13
14
  name?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/resource-browser",
3
- "version": "3.3.10",
3
+ "version": "3.3.11",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "private": false,
@@ -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
  });
@@ -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
  });
@@ -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 = Boolean((props.source as ResourceBrowserSourceWithConfig)?.configuration?.authUrl);
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
 
@@ -7,6 +7,7 @@ interface AuthContextProps {
7
7
  isAuthenticated: boolean;
8
8
  login: () => void;
9
9
  refreshAccessToken: () => Promise<any>;
10
+ alwaysUseResourceRequestProxy: boolean;
10
11
  }
11
12
 
12
13
  export const AuthContext = createContext<AuthContextProps | undefined>(undefined);
package/src/types.ts CHANGED
@@ -10,6 +10,9 @@ export type AuthenticationConfiguration = {
10
10
  redirectUrl: string;
11
11
  clientId: string;
12
12
  scope: string;
13
+
14
+ // Route all DAM requests through the DAM proxy
15
+ alwaysUseResourceRequestProxy?: boolean;
13
16
  };
14
17
 
15
18
  export interface ResourceBrowserSource {