diff --git a/demos/next-auth/package.json b/demos/next-auth/package.json index 919d52afb7..771e010184 100644 --- a/demos/next-auth/package.json +++ b/demos/next-auth/package.json @@ -24,7 +24,7 @@ "license": "MIT", "dependencies": { "next": "^12.3.2-canary.43", - "next-auth": "^4.7.0", + "next-auth": "^4.15.0", "nodemailer": "^6.6.3", "react": "^18.0.0", "react-dom": "^18.0.0" @@ -45,4 +45,4 @@ "engines": { "node": ">=16.0.0" } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index 722e4f46a1..5dee76533a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -214,7 +214,7 @@ "license": "MIT", "dependencies": { "next": "^12.3.2-canary.43", - "next-auth": "^4.7.0", + "next-auth": "^4.15.0", "nodemailer": "^6.6.3", "react": "^18.0.0", "react-dom": "^18.0.0" @@ -8129,9 +8129,9 @@ } }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } @@ -14786,9 +14786,9 @@ } }, "node_modules/jose": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.8.3.tgz", - "integrity": "sha512-7rySkpW78d8LBp4YU70Wb7+OTgE3OwAALNVZxhoIhp4Kscp+p/fBkdpxGAMKxvCAMV4QfXBU9m6l9nX/vGwd2g==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.10.0.tgz", + "integrity": "sha512-KEhB/eLGLomWGPTb+/RNbYsTjIyx03JmbqAyIyiXBuNSa7CmNrJd5ysFhblayzs/e/vbOPMUaLnjHUMhGp4yLw==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -17054,14 +17054,14 @@ } }, "node_modules/next-auth": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.10.3.tgz", - "integrity": "sha512-7zc4aXYc/EEln7Pkcsn21V1IevaTZsMLJwapfbnKA4+JY0+jFzWbt5p/ljugesGIrN4VOZhpZIw50EaFZyghJQ==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.15.0.tgz", + "integrity": "sha512-IasNzGLM2VlmyioDdZaRwBBBm8b5xo+zbbqVWHFh0bY6iQUZ3vuudrsdHNdxkXV3LSHdKNaoWEpYr4BydB7mCw==", "dependencies": { "@babel/runtime": "^7.16.3", "@panva/hkdf": "^1.0.1", - "cookie": "^0.4.1", - "jose": "^4.3.7", + "cookie": "^0.5.0", + "jose": "^4.9.3", "oauth": "^0.9.15", "openid-client": "^5.1.0", "preact": "^10.6.3", @@ -17072,6 +17072,7 @@ "node": "^12.19.0 || ^14.15.0 || ^16.13.0" }, "peerDependencies": { + "next": "^12.2.5", "nodemailer": "^6.6.5", "react": "^17.0.2 || ^18", "react-dom": "^17.0.2 || ^18" @@ -29081,9 +29082,9 @@ } }, "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, "cookie-es": { "version": "0.5.0", @@ -34145,9 +34146,9 @@ } }, "jose": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.8.3.tgz", - "integrity": "sha512-7rySkpW78d8LBp4YU70Wb7+OTgE3OwAALNVZxhoIhp4Kscp+p/fBkdpxGAMKxvCAMV4QfXBU9m6l9nX/vGwd2g==" + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.10.0.tgz", + "integrity": "sha512-KEhB/eLGLomWGPTb+/RNbYsTjIyx03JmbqAyIyiXBuNSa7CmNrJd5ysFhblayzs/e/vbOPMUaLnjHUMhGp4yLw==" }, "js-tokens": { "version": "4.0.0", @@ -35952,14 +35953,14 @@ } }, "next-auth": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.10.3.tgz", - "integrity": "sha512-7zc4aXYc/EEln7Pkcsn21V1IevaTZsMLJwapfbnKA4+JY0+jFzWbt5p/ljugesGIrN4VOZhpZIw50EaFZyghJQ==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.15.0.tgz", + "integrity": "sha512-IasNzGLM2VlmyioDdZaRwBBBm8b5xo+zbbqVWHFh0bY6iQUZ3vuudrsdHNdxkXV3LSHdKNaoWEpYr4BydB7mCw==", "requires": { "@babel/runtime": "^7.16.3", "@panva/hkdf": "^1.0.1", - "cookie": "^0.4.1", - "jose": "^4.3.7", + "cookie": "^0.5.0", + "jose": "^4.9.3", "oauth": "^0.9.15", "openid-client": "^5.1.0", "preact": "^10.6.3", @@ -35977,7 +35978,7 @@ "@types/react": "^18.0.0", "husky": "^7.0.4", "next": "^12.3.2-canary.43", - "next-auth": "^4.7.0", + "next-auth": "^4.15.0", "nodemailer": "^6.6.3", "npm-run-all": "^4.1.5", "react": "^18.0.0", diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index 37f67f6aa4..33723b3760 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -136,7 +136,11 @@ const plugin: NetlifyPlugin = { await updateRequiredServerFiles(publish, config) } else { - const nextAuthUrl = `${process.env.DEPLOY_PRIME_URL}${basePath}` + // Using the deploy prime url in production leads to issues because the unique deploy ID is part of the generated URL + // and will not match the expected URL in the callback URL of an OAuth application. + const nextAuthUrl = `${ + process.env.CONTEXT === 'production' ? process.env.URL : process.env.DEPLOY_PRIME_URL + }${basePath}` console.log(`NextAuth package detected, setting NEXTAUTH_URL environment variable to ${nextAuthUrl}`) config.config.env.NEXTAUTH_URL = nextAuthUrl diff --git a/test/index.js b/test/index.js index 842ae14f5e..f5b83597fd 100644 --- a/test/index.js +++ b/test/index.js @@ -232,6 +232,8 @@ describe('onBuild()', () => { afterEach(() => { delete process.env.DEPLOY_PRIME_URL + delete process.env.URL + delete process.env.CONTEXT }) test('does not set NEXTAUTH_URL if value is already set', async () => { @@ -253,6 +255,53 @@ describe('onBuild()', () => { expect(config.config.env.NEXTAUTH_URL).toEqual(mockUserDefinedSiteUrl) }) + test('sets the NEXTAUTH_URL to the DEPLOY_PRIME_URL when CONTEXT env variable is not \'production\'', async () => { + const mockUserDefinedSiteUrl = chance.url() + process.env.DEPLOY_PRIME_URL = mockUserDefinedSiteUrl + process.env.URL = chance.url() + + // See https://docs.netlify.com/configure-builds/environment-variables/#build-metadata for all possible values + process.env.CONTEXT = 'deploy-preview' + + await moveNextDist() + + const initialConfig = await getRequiredServerFiles(netlifyConfig.build.publish) + + initialConfig.config.env.NEXTAUTH_URL = mockUserDefinedSiteUrl + await updateRequiredServerFiles(netlifyConfig.build.publish, initialConfig) + + await nextRuntime.onBuild(defaultArgs) + + expect(onBuildHasRun(netlifyConfig)).toBe(true) + const config = await getRequiredServerFiles(netlifyConfig.build.publish) + + expect(config.config.env.NEXTAUTH_URL).toEqual(mockUserDefinedSiteUrl) + }) + + test('sets the NEXTAUTH_URL to the user defined site URL when CONTEXT env variable is \'production\'', async () => { + const mockUserDefinedSiteUrl = chance.url() + process.env.DEPLOY_PRIME_URL = chance.url() + process.env.URL = mockUserDefinedSiteUrl + + // See https://docs.netlify.com/configure-builds/environment-variables/#build-metadata for all possible values + process.env.CONTEXT = 'production' + + await moveNextDist() + + const initialConfig = await getRequiredServerFiles(netlifyConfig.build.publish) + + initialConfig.config.env.NEXTAUTH_URL = mockUserDefinedSiteUrl + await updateRequiredServerFiles(netlifyConfig.build.publish, initialConfig) + + await nextRuntime.onBuild(defaultArgs) + + expect(onBuildHasRun(netlifyConfig)).toBe(true) + const config = await getRequiredServerFiles(netlifyConfig.build.publish) + + expect(config.config.env.NEXTAUTH_URL).toEqual(mockUserDefinedSiteUrl) + }) + + test('sets the NEXTAUTH_URL specified in the netlify.toml or in the Netlify UI', async () => { const mockSiteUrl = chance.url() process.env.NEXTAUTH_URL = mockSiteUrl