Skip to content

Commit

Permalink
Simple auth state parsing with middleware in entry server
Browse files Browse the repository at this point in the history
  • Loading branch information
dac09 committed Oct 25, 2023
1 parent 9d4a1e7 commit 9e86135
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 20 deletions.
1 change: 1 addition & 0 deletions packages/api/src/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const getAuthenticationContext = async ({
}

const { schema, token } = parseAuthorizationHeader(event)
console.log(`👉 \n ~ file: index.ts:79 ~ token:`, token)

let authDecoders: Array<Decoder> = []

Expand Down
1 change: 1 addition & 0 deletions packages/auth-providers/dbAuth/api/src/decoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const createAuthDecoder = (cookieNameOption: string): Decoder => {
return null
}

// @TODO for SSR we need to make sure we are passing the cookie from the FE to the BE
const session = dbAuthSession(req.event, cookieNameOption)
const authHeaderUserId = token

Expand Down
7 changes: 5 additions & 2 deletions packages/auth/src/AuthProvider/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { ReactNode } from 'react'
import React, { useEffect, useState } from 'react'
import React, { useContext, useEffect, useState } from 'react'

import type { AuthContextInterface, CurrentUser } from '../AuthContext'
import type { AuthImplementation } from '../AuthImplementation'

import type { AuthProviderState } from './AuthProviderState'
import { defaultAuthProviderState } from './AuthProviderState'
import { ServerAuthContext } from './ServerAuthProvider'
import { useCurrentUser } from './useCurrentUser'
import { useForgotPassword } from './useForgotPassword'
import { useHasRole } from './useHasRole'
Expand Down Expand Up @@ -82,9 +83,11 @@ export function createAuthProvider<
}: AuthProviderProps) => {
// const [hasRestoredState, setHasRestoredState] = useState(false)

const serverAuthState = useContext(ServerAuthContext)

const [authProviderState, setAuthProviderState] = useState<
AuthProviderState<TUser>
>(defaultAuthProviderState)
>(serverAuthState || defaultAuthProviderState)

const getToken = useToken(authImplementation)

Expand Down
10 changes: 10 additions & 0 deletions packages/auth/src/AuthProvider/ServerAuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'

import type { AuthProviderState } from './AuthProviderState'
import { defaultAuthProviderState } from './AuthProviderState'

export const ServerAuthContext = React.createContext<
AuthProviderState<never> | undefined
>(defaultAuthProviderState)

export const ServerAuthProvider = ServerAuthContext.Provider
2 changes: 2 additions & 0 deletions packages/auth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export { AuthContextInterface, CurrentUser } from './AuthContext'
export { useNoAuth, UseAuth } from './useAuth'
export { createAuthentication } from './authFactory'
export type { AuthImplementation } from './AuthImplementation'

export * from './AuthProvider/ServerAuthProvider'
9 changes: 9 additions & 0 deletions packages/vite/src/streaming/createReactStreamingHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export const createReactStreamingHandler = async (
})
}

let decodedAuthState

// Do this inside the handler for **dev-only**.
// This makes sure that changes to entry-server are picked up on refresh
if (!isProd) {
Expand All @@ -59,6 +61,12 @@ export const createReactStreamingHandler = async (
fallbackDocumentImport = await viteDevServer.ssrLoadModule(
rwPaths.web.document
)

const middleware = entryServerImport.middleware

if (middleware) {
decodedAuthState = await middleware(req)
}
}

const ServerEntry =
Expand Down Expand Up @@ -112,6 +120,7 @@ export const createReactStreamingHandler = async (
cssLinks,
isProd,
jsBundles,
authState: decodedAuthState,
},
{
waitForAllReady: isSeoCrawler,
Expand Down
25 changes: 18 additions & 7 deletions packages/vite/src/streaming/streamHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import type {
ReactDOMServerReadableStream,
} from 'react-dom/server'

import { ServerAuthProvider } from '@redwoodjs/auth'
import type { AuthProviderState } from '@redwoodjs/auth/src/AuthProvider/AuthProviderState'
import type { TagDescriptor } from '@redwoodjs/web'
// @TODO (ESM), use exports field. Cannot import from web because of index exports
import {
Expand All @@ -26,6 +28,7 @@ interface RenderToStreamArgs {
cssLinks: string[]
isProd: boolean
jsBundles?: string[]
authState?: AuthProviderState<never> | undefined
}

interface StreamOptions {
Expand All @@ -46,7 +49,9 @@ export async function reactRenderToStreamResponse(
cssLinks,
isProd,
jsBundles = [],
authState,
} = renderOptions
console.log(`👉 \n ~ file: streamHelpers.ts:54 ~ authState:`, authState)

if (!isProd) {
// For development, we need to inject the react-refresh runtime
Expand Down Expand Up @@ -84,15 +89,21 @@ export async function reactRenderToStreamResponse(

const renderRoot = (path: string) => {
return React.createElement(
ServerHtmlProvider,
ServerAuthProvider,
{
value: injectToPage,
value: authState,
},
ServerEntry({
url: path,
css: cssLinks,
meta: metaTags,
})
React.createElement(
ServerHtmlProvider,
{
value: injectToPage,
},
ServerEntry({
url: path,
css: cssLinks,
meta: metaTags,
})
)
)
}

Expand Down
11 changes: 0 additions & 11 deletions packages/web/src/components/ServerInject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,3 @@ export function useServerInsertedHTML(callback: () => React.ReactNode): void {
addInsertedServerHTMLCallback(callback)
}
}

// @TODO use this in streamHelpers final block
export const AppendToHead = ({ tagsToAppend }: { tagsToAppend: string }) => {
return (
<script
dangerouslySetInnerHTML={{
__html: `document?.head.append(${tagsToAppend})`,
}}
/>
)
}

0 comments on commit 9e86135

Please sign in to comment.