Skip to content

Commit

Permalink
Merge branch 'main' of github.com:redwoodjs/redwood into feat/extract…
Browse files Browse the repository at this point in the history
…-role-authmw

* 'main' of github.com:redwoodjs/redwood:
  fix(dbAuthMw): Update and fix logic related to dbAuth "verbs" and decryptionErrors (redwoodjs#10668)
  RSC: routes-auto-loader is not used for SSR anymore (redwoodjs#10672)
  chore(crwa): Remove unused jest dev dependency (redwoodjs#10673)
  RSC: rscBuildEntriesFile: Only ServerEntry and Routes needed for serverEntries (redwoodjs#10671)
  RSC: clientSsr: getServerEntryComponent() (redwoodjs#10670)
  RSC: worker: getFunctionComponent -> getRoutesComponent (redwoodjs#10669)
  RSC: kitchen-sink: Make the ReadFileServerCell output take up less space (redwoodjs#10667)
  RSC: Remove commented code related to prefixToRemove transform() (redwoodjs#10666)
  RSC Client Router (redwoodjs#10557)
  RSC: Add 'use client' to remaining client cells in kitchen-sink (redwoodjs#10665)
  RSC: vite auto-loader: Spell out 'path' and other chores (redwoodjs#10662)
  fix(cli): Handle case for no arguments for verbose baremetal deploy  (redwoodjs#10663)
  RSC: kitchen-sink: Make it more clear where layout ends and main content starts (redwoodjs#10661)
  RSC: Make the kitchen-sink smoke-test more robust/resilient (redwoodjs#10660)
  RSC: Source format of EmptyUsersCell in kitchen-sink (redwoodjs#10658)
  RSC: Add 'use client' to all client cells in kitchen-sink (redwoodjs#10659)
  chore(__fixtures__): Follow-up: Make test projects match newer CRWA template (redwoodjs#10657)
  feat: Reworks RSC server entries and route manifest building to derive from routes and include if route info related to authentication (redwoodjs#10572)
  chore(__fixtures__): Make test projects match newer CRWA template (redwoodjs#10655)
  • Loading branch information
dac09 committed May 22, 2024
2 parents 5f47249 + a51b168 commit a1a2caa
Show file tree
Hide file tree
Showing 58 changed files with 951 additions and 362 deletions.
15 changes: 15 additions & 0 deletions .changesets/10572.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
- feat: feat: Reworks RSC server entries and route manifest building to derive from routes and include if route info related to authentication (#10572) by @dthyresson

This PR is in furtherance of authentication support in RSC.

It refactors:

- How server entries are built -- not from "processing the pages dir" (which is a deprecated function) but rather the routes ... and the page info for that route. Note here that a page can be used in multiple routes, so the auth info cannot really be determined here.

- The route manifest building to include per route:

* isPrivate - is the route private, i.e, is it wrapped in a PrivateSet
* unauthenticated - what route to navigate to if the user in not authenticated
* roles - the roles to check to see if user has the require RBAC permission to navigate to the route

Now if some page, route request is being handled by RSC we might be able to check if it "isPrivate" and enforce auth with the roles and even where tp redirect to if not authenticated.
4 changes: 4 additions & 0 deletions .changesets/10663.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- fix(cli): Handle case for no arguments for verbose baremetal deploy (#10663) by @Josh-Walker-GM

The change corrects a bug during baremetal deployments when using the `--verbose` flag. See #10654 for more details.

10 changes: 10 additions & 0 deletions .changesets/10668.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- fix(dbAuthMw): Update and fix logic related to dbAuth "verbs" and decryptionErrors (#10668) by @dac09

This PR does the following:
- updates the dbauth mw to correctly handle the cookieName option (it should always have been optional)
- throws an error when the `dbAuthSession` returns an empty decoded token so that it clears the authState
- we had a check for only "POST" requests to be passed to the dbAuthHandler. This was incorrect because some of the dbAuth "verbs" or actions - like `webAuthnRegOptions` - uses a GET request.

As a result, the tests started showing failures, so I:
- added a mock for `dbAuthSession`, so we can check both happy path and unhappy paths for session decryption
- updated the tests where relevant
12 changes: 9 additions & 3 deletions __fixtures__/example-todo-main/web/src/Routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// 'src/pages/HomePage/HomePage.js' -> HomePage
// 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage

import { Private, Router, Route } from '@redwoodjs/router'
import { PrivateSet, Router, Route } from '@redwoodjs/router'
import SetLayout from 'src/layouts/SetLayout'

import FooPage from 'src/pages/FooPage'
Expand All @@ -22,9 +22,15 @@ const Routes = () => {
<Route path="/foo" page={FooPage} name="fooPage" />
<Route path="/bar" page={BarPage} name="barPage" />
</Set>
<Private prerender unauthenticated="home">
<PrivateSet unauthenticated="home" prerender>
<Route path="/private-page" page={PrivatePage} name="privatePage" />
</Private>
</PrivateSet>
<PrivateSet unauthenticated="home" roles="admin" prerender>
<Route path="/private-page-admin" page={PrivatePage} name="privatePageAdmin" />
</PrivateSet>
<PrivateSet unauthenticated="home" roles={['owner', 'superuser']} prerender>
<Route path="/private-page-admin-super" page={PrivatePage} name="privatePageAdminSuper" />
</PrivateSet>
<Route notfound page={NotFoundPage} />
</Router>
)
Expand Down
11 changes: 8 additions & 3 deletions __fixtures__/fragment-test-project/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import type { ReactNode } from 'react'

import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import { AuthProvider, useAuth } from './auth'

import './scaffold.css'
import './index.css'

const App = () => (
interface AppProps {
children?: ReactNode
}

const App = ({ children }: AppProps) => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<AuthProvider>
<RedwoodApolloProvider useAuth={useAuth}>
<Routes />
{children}
</RedwoodApolloProvider>
</AuthProvider>
</RedwoodProvider>
Expand Down
6 changes: 3 additions & 3 deletions __fixtures__/fragment-test-project/web/src/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// 'src/pages/HomePage/HomePage.js' -> HomePage
// 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage

import { Router, Route, Private, Set } from '@redwoodjs/router'
import { Router, Route, PrivateSet, Set } from '@redwoodjs/router'

import BlogLayout from 'src/layouts/BlogLayout'
import ScaffoldLayout from 'src/layouts/ScaffoldLayout'
Expand Down Expand Up @@ -38,9 +38,9 @@ const Routes = () => {
</Set>
<Set wrap={BlogLayout}>
<Route path="/waterfall/{id:Int}" page={WaterfallPage} prerender name="waterfall" />
<Private unauthenticated="login">
<PrivateSet unauthenticated="login">
<Route path="/profile" page={ProfilePage} name="profile" />
</Private>
</PrivateSet>
<Route path="/blog-post/{id:Int}" page={BlogPostPage} name="blogPost" prerender />
<Route path="/contact" page={ContactUsPage} name="contactUs" />
<Route path="/about" page={AboutPage} name="about" prerender />
Expand Down
17 changes: 14 additions & 3 deletions __fixtures__/fragment-test-project/web/src/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { hydrateRoot, createRoot } from 'react-dom/client'

import App from './App'
import Routes from './Routes'

/**
* When `#redwood-app` isn't empty then it's very likely that you're using
* prerendering. So React attaches event listeners to the existing markup
Expand All @@ -11,13 +13,22 @@ const redwoodAppElement = document.getElementById('redwood-app')

if (!redwoodAppElement) {
throw new Error(
"Could not find an element with ID 'redwood-app'. Please ensure it exists in your 'web/src/index.html' file."
"Could not find an element with ID 'redwood-app'. Please ensure it " +
"exists in your 'web/src/index.html' file."
)
}

if (redwoodAppElement.children?.length > 0) {
hydrateRoot(redwoodAppElement, <App />)
hydrateRoot(redwoodAppElement,
<App>
<Routes />
</App>
)
} else {
const root = createRoot(redwoodAppElement)
root.render(<App />)
root.render(
<App>
<Routes />
</App>
)
}
13 changes: 8 additions & 5 deletions __fixtures__/test-project-rsa/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import type { ReactNode } from 'react'

import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import FatalErrorPage from './pages/FatalErrorPage/FatalErrorPage'
import Routes from './Routes'

import './index.css'

const App = () => (
interface AppProps {
children?: ReactNode
}

const App = ({ children }: AppProps) => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<RedwoodApolloProvider>
<Routes />
</RedwoodApolloProvider>
<RedwoodApolloProvider>{children}</RedwoodApolloProvider>
</RedwoodProvider>
</FatalErrorBoundary>
)
Expand Down
11 changes: 8 additions & 3 deletions __fixtures__/test-project-rsa/web/src/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@
// 'src/pages/HomePage/HomePage.js' -> HomePage
// 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage

import { Router, Route, Set } from '@redwoodjs/router'
import { Route } from '@redwoodjs/router/dist/Route'
import { Set } from '@redwoodjs/router/dist/Set'

// @ts-expect-error - ESM issue. RW projects need to be ESM to properly pick up
// on the types here
import { Router } from '@redwoodjs/vite/Router'

import NavigationLayout from './layouts/NavigationLayout/NavigationLayout'
import NotFoundPage from './pages/NotFoundPage/NotFoundPage'

const Routes = () => {
const Routes = ({ location }: { location?: any }) => {
return (
<Router>
<Router location={location}>
<Set wrap={NavigationLayout}>
<Route path="/" page={HomePage} name="home" />
<Route path="/about" page={AboutPage} name="about" />
Expand Down
18 changes: 15 additions & 3 deletions __fixtures__/test-project-rsa/web/src/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { hydrateRoot, createRoot } from 'react-dom/client'

import App from './App'
import Routes from './Routes'

/**
* When `#redwood-app` isn't empty then it's very likely that you're using
* prerendering. So React attaches event listeners to the existing markup
Expand All @@ -11,13 +13,23 @@ const redwoodAppElement = document.getElementById('redwood-app')

if (!redwoodAppElement) {
throw new Error(
"Could not find an element with ID 'redwood-app'. Please ensure it exists in your 'web/src/index.html' file."
"Could not find an element with ID 'redwood-app'. Please ensure it " +
"exists in your 'web/src/index.html' file."
)
}

if (redwoodAppElement.children?.length > 0) {
hydrateRoot(redwoodAppElement, <App />)
hydrateRoot(
redwoodAppElement,
<App>
<Routes />
</App>
)
} else {
const root = createRoot(redwoodAppElement)
root.render(<App />)
root.render(
<App>
<Routes />
</App>
)
}
10 changes: 8 additions & 2 deletions __fixtures__/test-project-rsa/web/src/entry.server.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import type { TagDescriptor } from '@redwoodjs/web/dist/components/htmlTags'

import { Document } from './Document'
import Routes from './Routes'

interface Props {
css: string[]
meta?: TagDescriptor[]
location: {
pathname: string
hash?: string
search?: string
}
}

export const ServerEntry: React.FC<Props> = ({ css, meta }) => {
export const ServerEntry: React.FC<Props> = ({ css, meta, location }) => {
return (
<Document css={css} meta={meta}>
<div>App</div>
<Routes location={location} />
</Document>
)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Link, routes } from '@redwoodjs/router'
import { namedRoutes as routes } from '@redwoodjs/router/dist/namedRoutes'

import './NavigationLayout.css'

type NavigationLayoutProps = {
children?: React.ReactNode
}

const Link = (props: any) => {
return <a href={props.to}>{props.children}</a>
}

const NavigationLayout = ({ children }: NavigationLayoutProps) => {
return (
<div className="navigation-layout">
Expand Down
13 changes: 8 additions & 5 deletions __fixtures__/test-project-rsc-kitchen-sink/web/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import type { ReactNode } from 'react'

import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import FatalErrorPage from './pages/FatalErrorPage/FatalErrorPage'
import Routes from './Routes'

import './index.css'
import './scaffold.css'

const App = () => (
interface AppProps {
children?: ReactNode
}

const App = ({ children }: AppProps) => (
<FatalErrorBoundary page={FatalErrorPage}>
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
<RedwoodApolloProvider>
<Routes />
</RedwoodApolloProvider>
<RedwoodApolloProvider>{children}</RedwoodApolloProvider>
</RedwoodProvider>
</FatalErrorBoundary>
)
Expand Down
20 changes: 12 additions & 8 deletions __fixtures__/test-project-rsc-kitchen-sink/web/src/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,34 @@
// 'src/pages/HomePage/HomePage.js' -> HomePage
// 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage

import { Router, Route, Set } from '@redwoodjs/router'
import { Route } from '@redwoodjs/router/dist/Route'
import { Set } from '@redwoodjs/router/dist/Set'

// @ts-expect-error - ESM issue. RW projects need to be ESM to properly pick up
// on the types here
import { Router } from '@redwoodjs/vite/Router'

import NavigationLayout from './layouts/NavigationLayout/NavigationLayout'
import ScaffoldLayout from './layouts/ScaffoldLayout/ScaffoldLayout'
import NotFoundPage from './pages/NotFoundPage/NotFoundPage'

const Routes = () => {
const Routes = ({ location }: { location?: any }) => {
return (
<Router>
<Set wrap={NavigationLayout}>
<Router location={location}>
<Set wrap={NavigationLayout} rnd={0.7}>
<Route path="/" page={HomePage} name="home" />
<Route path="/about" page={AboutPage} name="about" />
<Route path="/multi-cell" page={MultiCellPage} name="multiCell" />

<Set wrap={ScaffoldLayout} title="EmptyUsers" titleTo="emptyUsers" buttonLabel="New EmptyUser" buttonTo="newEmptyUser">
<Route path="/empty-users/new" page={EmptyUserNewEmptyUserPage} name="newEmptyUser" />
{/* <Route path="/empty-users/{id:Int}/edit" page={EmptyUserEditEmptyUserPage} name="editEmptyUser" />
<Route path="/empty-users/{id:Int}" page={EmptyUserEmptyUserPage} name="emptyUser" /> */}
<Route path="/empty-users/{id:Int}/edit" page={EmptyUserEditEmptyUserPage} name="editEmptyUser" />
<Route path="/empty-users/{id:Int}" page={EmptyUserEmptyUserPage} name="emptyUser" />
<Route path="/empty-users" page={EmptyUserEmptyUsersPage} name="emptyUsers" />
</Set>

<Set wrap={ScaffoldLayout} title="UserExamples" titleTo="userExamples" buttonLabel="New UserExample" buttonTo="newUserExample">
<Route path="/user-examples/new" page={UserExampleNewUserExamplePage} name="newUserExample" />
{/* <Route path="/user-examples/{id:Int}/edit" page={UserExampleEditUserExamplePage} name="editUserExample" /> */}
<Route path="/user-examples/{id:Int}/edit" page={UserExampleEditUserExamplePage} name="editUserExample" />
<Route path="/user-examples/{id:Int}" page={UserExampleUserExamplePage} name="userExample" />
<Route path="/user-examples" page={UserExampleUserExamplesPage} name="userExamples" />
</Set>
Expand Down
Loading

0 comments on commit a1a2caa

Please sign in to comment.