Skip to content

Commit 1fffeb0

Browse files
kengreeffTobbethedavidprice
authored
4593 BUG - Auth setup script issues (redwoodjs#4825)
Co-authored-by: Tobbe Lundberg <[email protected]> Co-authored-by: David Price <[email protected]>
1 parent 304dddf commit 1fffeb0

File tree

6 files changed

+300
-24
lines changed

6 files changed

+300
-24
lines changed

packages/cli/src/commands/setup/auth/__tests__/__snapshots__/addAuthConfigToApp.test.js.snap

+152
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,111 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Should add auth config when app is missing RedwoodApolloProvider Matches Auth0 Snapshot 1`] = `
4+
"import { AuthProvider } from '@redwoodjs/auth'
5+
import { Auth0Client } from '@auth0/auth0-spa-js'
6+
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
7+
8+
import FatalErrorPage from 'src/pages/FatalErrorPage'
9+
import Routes from 'src/Routes'
10+
11+
import './index.css'
12+
13+
const queryClient = {}
14+
15+
const auth0 = new Auth0Client({
16+
domain: process.env.AUTH0_DOMAIN,
17+
client_id: process.env.AUTH0_CLIENT_ID,
18+
redirect_uri: process.env.AUTH0_REDIRECT_URI,
19+
20+
// ** NOTE ** Storing tokens in browser local storage provides persistence across page refreshes and browser tabs.
21+
// However, if an attacker can achieve running JavaScript in the SPA using a cross-site scripting (XSS) attack,
22+
// they can retrieve the tokens stored in local storage.
23+
// https://auth0.com/docs/libraries/auth0-spa-js#change-storage-options
24+
cacheLocation: 'localstorage',
25+
audience: process.env.AUTH0_AUDIENCE,
26+
27+
// @MARK: useRefreshTokens is required for automatically extending sessions
28+
// beyond that set in the initial JWT expiration.
29+
//
30+
// @MARK: https://auth0.com/docs/tokens/refresh-tokens
31+
// useRefreshTokens: true,
32+
})
33+
34+
const App = () => (
35+
<FatalErrorBoundary page={FatalErrorPage}>
36+
<RedwoodProvider titleTemplate=\\"%PageTitle | %AppTitle\\">
37+
<AuthProvider client={auth0} type=\\"auth0\\">
38+
<QueryClientProvider client={queryClient}>
39+
<RedwoodReactQueryProvider>
40+
<Routes />
41+
</RedwoodReactQueryProvider>
42+
</QueryClientProvider>
43+
</AuthProvider>
44+
</RedwoodProvider>
45+
</FatalErrorBoundary>
46+
)
47+
48+
export default App
49+
"
50+
`;
51+
52+
exports[`Should add auth config when using explicit return Matches Auth0 Snapshot 1`] = `
53+
"import { AuthProvider } from '@redwoodjs/auth'
54+
import { Auth0Client } from '@auth0/auth0-spa-js'
55+
import { useEffect } from 'react'
56+
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
57+
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'
58+
59+
import FatalErrorPage from 'src/pages/FatalErrorPage'
60+
import Routes from 'src/Routes'
61+
62+
import './index.css'
63+
64+
const auth0 = new Auth0Client({
65+
domain: process.env.AUTH0_DOMAIN,
66+
client_id: process.env.AUTH0_CLIENT_ID,
67+
redirect_uri: process.env.AUTH0_REDIRECT_URI,
68+
69+
// ** NOTE ** Storing tokens in browser local storage provides persistence across page refreshes and browser tabs.
70+
// However, if an attacker can achieve running JavaScript in the SPA using a cross-site scripting (XSS) attack,
71+
// they can retrieve the tokens stored in local storage.
72+
// https://auth0.com/docs/libraries/auth0-spa-js#change-storage-options
73+
cacheLocation: 'localstorage',
74+
audience: process.env.AUTH0_AUDIENCE,
75+
76+
// @MARK: useRefreshTokens is required for automatically extending sessions
77+
// beyond that set in the initial JWT expiration.
78+
//
79+
// @MARK: https://auth0.com/docs/tokens/refresh-tokens
80+
// useRefreshTokens: true,
81+
})
82+
83+
const App = (props) => {
84+
const { cache } = props
85+
86+
useEffect(() => {
87+
console.log('Running my custom useEffect hook on each render.')
88+
})
89+
90+
return (
91+
<FatalErrorBoundary page={FatalErrorPage}>
92+
<RedwoodProvider titleTemplate=\\"%PageTitle | %AppTitle\\">
93+
<AuthProvider client={auth0} type=\\"auth0\\">
94+
<RedwoodApolloProvider>
95+
<AnotherProvider>
96+
<Routes />
97+
</AnotherProvider>
98+
</RedwoodApolloProvider>
99+
</AuthProvider>
100+
</RedwoodProvider>
101+
</FatalErrorBoundary>
102+
)
103+
}
104+
105+
export default App
106+
"
107+
`;
108+
3109
exports[`Should add config lines to App.{js,tsx} Matches Auth0 Snapshot 1`] = `
4110
"import { AuthProvider } from '@redwoodjs/auth'
5111
import { Auth0Client } from '@auth0/auth0-spa-js'
@@ -357,3 +463,49 @@ const App = () => (
357463
export default App
358464
"
359465
`;
466+
467+
exports[`Should add config lines when RedwoodApolloProvider has props Matches Auth0 Snapshot 1`] = `
468+
"import { AuthProvider } from '@redwoodjs/auth'
469+
import { Auth0Client } from '@auth0/auth0-spa-js'
470+
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
471+
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'
472+
473+
import FatalErrorPage from 'src/pages/FatalErrorPage'
474+
import Routes from 'src/Routes'
475+
476+
import './index.css'
477+
478+
const auth0 = new Auth0Client({
479+
domain: process.env.AUTH0_DOMAIN,
480+
client_id: process.env.AUTH0_CLIENT_ID,
481+
redirect_uri: process.env.AUTH0_REDIRECT_URI,
482+
483+
// ** NOTE ** Storing tokens in browser local storage provides persistence across page refreshes and browser tabs.
484+
// However, if an attacker can achieve running JavaScript in the SPA using a cross-site scripting (XSS) attack,
485+
// they can retrieve the tokens stored in local storage.
486+
// https://auth0.com/docs/libraries/auth0-spa-js#change-storage-options
487+
cacheLocation: 'localstorage',
488+
audience: process.env.AUTH0_AUDIENCE,
489+
490+
// @MARK: useRefreshTokens is required for automatically extending sessions
491+
// beyond that set in the initial JWT expiration.
492+
//
493+
// @MARK: https://auth0.com/docs/tokens/refresh-tokens
494+
// useRefreshTokens: true,
495+
})
496+
497+
const App = () => (
498+
<FatalErrorBoundary page={FatalErrorPage}>
499+
<RedwoodProvider titleTemplate=\\"%PageTitle | %AppTitle\\">
500+
<AuthProvider client={auth0} type=\\"auth0\\">
501+
<RedwoodApolloProvider graphQLClientConfig={{ cache }}>
502+
<Routes />
503+
</RedwoodApolloProvider>
504+
</AuthProvider>
505+
</RedwoodProvider>
506+
</FatalErrorBoundary>
507+
)
508+
509+
export default App
510+
"
511+
`;

packages/cli/src/commands/setup/auth/__tests__/addAuthConfigToApp.test.js

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Have to use `var` here to avoid "Temporal Dead Zone" issues
2+
var mockWebAppPath = ''
3+
14
import fs from 'fs'
25

36
import '../../../../lib/mockTelemetry'
@@ -7,14 +10,15 @@ import { addConfigToApp } from '../auth'
710
jest.mock('../../../../lib', () => {
811
const path = require('path')
912
const __dirname = path.resolve()
13+
1014
return {
1115
getPaths: () => ({
1216
api: { functions: '', src: '', lib: '' },
1317
web: {
1418
src: path.join(__dirname, '../create-redwood-app/template/web/src'),
1519
app: path.join(
1620
__dirname,
17-
'../create-redwood-app/template/web/src/App.tsx'
21+
mockWebAppPath || '../create-redwood-app/template/web/src/App.tsx'
1822
),
1923
},
2024
}),
@@ -28,6 +32,7 @@ const writeFileSyncSpy = jest.fn((_, content) => {
2832
})
2933

3034
beforeEach(() => {
35+
mockWebAppPath = ''
3136
jest.restoreAllMocks()
3237
jest.spyOn(fs, 'writeFileSync').mockImplementation(writeFileSyncSpy)
3338
})
@@ -80,3 +85,33 @@ describe('Should add config lines to App.{js,tsx}', () => {
8085
await addConfigToApp(nhostData.config, false)
8186
})
8287
})
88+
89+
describe('Should add config lines when RedwoodApolloProvider has props', () => {
90+
it('Matches Auth0 Snapshot', async () => {
91+
mockWebAppPath =
92+
'src/commands/setup/auth/__tests__/fixtures/AppWithCustomRedwoodApolloProvider.js'
93+
94+
const auth0Data = await import(`../providers/auth0`)
95+
await addConfigToApp(auth0Data.config, false)
96+
})
97+
})
98+
99+
describe('Should add auth config when using explicit return', () => {
100+
it('Matches Auth0 Snapshot', async () => {
101+
mockWebAppPath =
102+
'src/commands/setup/auth/__tests__/fixtures/AppWithExplicitReturn.js'
103+
104+
const auth0Data = await import(`../providers/auth0`)
105+
await addConfigToApp(auth0Data.config, false)
106+
})
107+
})
108+
109+
describe('Should add auth config when app is missing RedwoodApolloProvider', () => {
110+
it('Matches Auth0 Snapshot', async () => {
111+
mockWebAppPath =
112+
'src/commands/setup/auth/__tests__/fixtures/AppWithoutRedwoodApolloProvider.js'
113+
114+
const auth0Data = await import(`../providers/auth0`)
115+
await addConfigToApp(auth0Data.config, false)
116+
})
117+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
2+
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'
3+
4+
import FatalErrorPage from 'src/pages/FatalErrorPage'
5+
import Routes from 'src/Routes'
6+
7+
import './index.css'
8+
9+
const App = () => (
10+
<FatalErrorBoundary page={FatalErrorPage}>
11+
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
12+
<RedwoodApolloProvider graphQLClientConfig={{ cache }}>
13+
<Routes />
14+
</RedwoodApolloProvider>
15+
</RedwoodProvider>
16+
</FatalErrorBoundary>
17+
)
18+
19+
export default App
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useEffect } from 'react'
2+
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
3+
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'
4+
5+
import FatalErrorPage from 'src/pages/FatalErrorPage'
6+
import Routes from 'src/Routes'
7+
8+
import './index.css'
9+
10+
const App = (props) => {
11+
const { cache } = props
12+
13+
useEffect(() => {
14+
console.log('Running my custom useEffect hook on each render.')
15+
})
16+
17+
return (
18+
<FatalErrorBoundary page={FatalErrorPage}>
19+
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
20+
<RedwoodApolloProvider>
21+
<AnotherProvider>
22+
<Routes />
23+
</AnotherProvider>
24+
</RedwoodApolloProvider>
25+
</RedwoodProvider>
26+
</FatalErrorBoundary>
27+
)
28+
}
29+
30+
export default App
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
2+
3+
import FatalErrorPage from 'src/pages/FatalErrorPage'
4+
import Routes from 'src/Routes'
5+
6+
import './index.css'
7+
8+
const queryClient = {}
9+
10+
const App = () => (
11+
<FatalErrorBoundary page={FatalErrorPage}>
12+
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
13+
<QueryClientProvider client={queryClient}>
14+
<RedwoodReactQueryProvider>
15+
<Routes />
16+
</RedwoodReactQueryProvider>
17+
</QueryClientProvider>
18+
</RedwoodProvider>
19+
</FatalErrorBoundary>
20+
)
21+
22+
export default App

0 commit comments

Comments
 (0)