Enforce CORS
This commit is contained in:
@ -39,9 +39,9 @@ FROM base as api_build
|
|||||||
# specify them here as ARGs. (But don't put secrets in your Dockerfile!)
|
# specify them here as ARGs. (But don't put secrets in your Dockerfile!)
|
||||||
|
|
||||||
ARG ADDRESS_PROD
|
ARG ADDRESS_PROD
|
||||||
ARG API_ADDRESS_PROD
|
|
||||||
ARG ADDRESS_DEV
|
ARG ADDRESS_DEV
|
||||||
ARG API_ADDRESS_DEV
|
ARG DOMAIN
|
||||||
|
ARG API_DOMAIN
|
||||||
ARG MAX_HTTP_CONNECTIONS_PER_MINUTE
|
ARG MAX_HTTP_CONNECTIONS_PER_MINUTE
|
||||||
ARG GMAIL
|
ARG GMAIL
|
||||||
ARG GMAIL_SMTP_PASSWORD
|
ARG GMAIL_SMTP_PASSWORD
|
||||||
|
@ -11,6 +11,22 @@ import { cookieName } from 'src/lib/auth'
|
|||||||
import { db } from 'src/lib/db'
|
import { db } from 'src/lib/db'
|
||||||
import { censorEmail, sendEmail } from 'src/lib/email'
|
import { censorEmail, sendEmail } from 'src/lib/email'
|
||||||
|
|
||||||
|
function getCommonCookieDomain(domain: string, apiDomain: string): string {
|
||||||
|
const splitDomain1 = domain.split('.').reverse()
|
||||||
|
const splitDomain2 = apiDomain.split('.').reverse()
|
||||||
|
const commonParts: string[] = []
|
||||||
|
|
||||||
|
for (let i = 0; i < Math.min(splitDomain1.length, splitDomain2.length); i++) {
|
||||||
|
if (splitDomain1[i] === splitDomain2[i]) commonParts.push(splitDomain1[i])
|
||||||
|
else break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commonParts.length < 2)
|
||||||
|
throw new Error('Domains do not share the same TLD')
|
||||||
|
|
||||||
|
return commonParts.reverse().join('.')
|
||||||
|
}
|
||||||
|
|
||||||
export const handler = async (
|
export const handler = async (
|
||||||
event: APIGatewayProxyEvent,
|
event: APIGatewayProxyEvent,
|
||||||
context: Context
|
context: Context
|
||||||
@ -197,10 +213,8 @@ ${domain}/reset-password?resetToken=${resetToken}
|
|||||||
},
|
},
|
||||||
|
|
||||||
cors: {
|
cors: {
|
||||||
origin: isProduction
|
origin: isProduction ? process.env.ADDRESS_PROD : process.env.ADDRESS_DEV,
|
||||||
? [process.env.ADDRESS_PROD, process.env.API_ADDRESS_PROD]
|
credentials: isProduction,
|
||||||
: [process.env.ADDRESS_DEV, process.env.API_ADDRESS_DEV],
|
|
||||||
credentials: true,
|
|
||||||
methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH'],
|
methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH'],
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -218,7 +232,9 @@ ${domain}/reset-password?resetToken=${resetToken}
|
|||||||
Path: '/',
|
Path: '/',
|
||||||
SameSite: isProduction ? 'None' : 'Strict',
|
SameSite: isProduction ? 'None' : 'Strict',
|
||||||
Secure: isProduction,
|
Secure: isProduction,
|
||||||
Domain: isProduction ? process.env.DOMAIN : 'localhost',
|
Domain: isProduction
|
||||||
|
? getCommonCookieDomain(process.env.DOMAIN, process.env.API_DOMAIN)
|
||||||
|
: 'localhost',
|
||||||
},
|
},
|
||||||
name: cookieName,
|
name: cookieName,
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
HexColorCodeResolver,
|
HexColorCodeResolver,
|
||||||
} from 'graphql-scalars'
|
} from 'graphql-scalars'
|
||||||
|
|
||||||
|
import { isProduction } from '@redwoodjs/api/logger'
|
||||||
import { createAuthDecoder } from '@redwoodjs/auth-dbauth-api'
|
import { createAuthDecoder } from '@redwoodjs/auth-dbauth-api'
|
||||||
import { createGraphQLHandler } from '@redwoodjs/graphql-server'
|
import { createGraphQLHandler } from '@redwoodjs/graphql-server'
|
||||||
|
|
||||||
@ -32,5 +33,9 @@ export const handler = createGraphQLHandler({
|
|||||||
HexColorCode: HexColorCodeResolver,
|
HexColorCode: HexColorCodeResolver,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
cors: {
|
||||||
|
origin: isProduction ? process.env.ADDRESS_PROD : process.env.ADDRESS_DEV,
|
||||||
|
credentials: isProduction,
|
||||||
|
},
|
||||||
onException: () => db.$disconnect(),
|
onException: () => db.$disconnect(),
|
||||||
})
|
})
|
||||||
|
@ -15,8 +15,8 @@ import { handleTusUpload } from 'src/lib/tus'
|
|||||||
configureApiServer: async (server) => {
|
configureApiServer: async (server) => {
|
||||||
await server.register(Cors, {
|
await server.register(Cors, {
|
||||||
origin: isProduction
|
origin: isProduction
|
||||||
? [process.env.ADDRESS_PROD, process.env.API_ADDRESS_PROD]
|
? process.env.ADDRESS_PROD
|
||||||
: [process.env.ADDRESS_DEV, process.env.API_ADDRESS_DEV],
|
: process.env.ADDRESS_DEV,
|
||||||
methods: ['GET', 'POST', 'OPTIONS', 'PATCH', 'HEAD'],
|
methods: ['GET', 'POST', 'OPTIONS', 'PATCH', 'HEAD'],
|
||||||
credentials: isProduction ? true : false,
|
credentials: isProduction ? true : false,
|
||||||
})
|
})
|
||||||
|
@ -12,7 +12,14 @@ const App = () => (
|
|||||||
<FatalErrorBoundary page={FatalErrorPage}>
|
<FatalErrorBoundary page={FatalErrorPage}>
|
||||||
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
|
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<RedwoodApolloProvider useAuth={useAuth}>
|
<RedwoodApolloProvider
|
||||||
|
useAuth={useAuth}
|
||||||
|
graphQLClientConfig={{
|
||||||
|
httpLinkConfig: {
|
||||||
|
credentials: 'include',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Routes />
|
<Routes />
|
||||||
</RedwoodApolloProvider>
|
</RedwoodApolloProvider>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import { createDbAuthClient, createAuth } from '@redwoodjs/auth-dbauth-web'
|
import { createDbAuthClient, createAuth } from '@redwoodjs/auth-dbauth-web'
|
||||||
|
|
||||||
const dbAuthClient = createDbAuthClient()
|
const dbAuthClient = createDbAuthClient({
|
||||||
|
fetchConfig: {
|
||||||
|
credentials: 'include',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
export const { AuthProvider, useAuth } = createAuth(dbAuthClient)
|
export const { AuthProvider, useAuth } = createAuth(dbAuthClient)
|
||||||
|
Reference in New Issue
Block a user