Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: include identity context data under custom netlify client context #6277

Merged
merged 1 commit into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions src/lib/functions/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,35 @@ const buildClientContext = function (headers) {
const parts = headers.authorization.split(' ')
if (parts.length !== 2 || parts[0] !== 'Bearer') return

const identity = {
url: 'https://netlify-dev-locally-emulated-identity.netlify.com/.netlify/identity',
token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb3VyY2UiOiJuZXRsaWZ5IGRldiIsInRlc3REYXRhIjoiTkVUTElGWV9ERVZfTE9DQUxMWV9FTVVMQVRFRF9JREVOVElUWSJ9.2eSDqUOZAOBsx39FHFePjYj12k0LrxldvGnlvDu3GMI',
// you can decode this with https://jwt.io/
// just says
// {
// "source": "netlify dev",
// "testData": "NETLIFY_DEV_LOCALLY_EMULATED_IDENTITY"
// }
}

// This data is available on both the context root and under custom.netlify for retro-compatibility.
// In the future it will only be available in custom.netlify.
// @ts-expect-error
const user = jwtDecode(parts[1])

const netlifyContext = JSON.stringify({
identity: identity,
user: user,
})

try {
return {
identity: {
url: 'https://netlify-dev-locally-emulated-identity.netlify.com/.netlify/identity',
token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb3VyY2UiOiJuZXRsaWZ5IGRldiIsInRlc3REYXRhIjoiTkVUTElGWV9ERVZfTE9DQUxMWV9FTVVMQVRFRF9JREVOVElUWSJ9.2eSDqUOZAOBsx39FHFePjYj12k0LrxldvGnlvDu3GMI',
// you can decode this with https://jwt.io/
// just says
// {
// "source": "netlify dev",
// "testData": "NETLIFY_DEV_LOCALLY_EMULATED_IDENTITY"
// }
identity: identity,
user: user,
custom: {
netlify: Buffer.from(netlifyContext).toString('base64'),
},
// @ts-expect-error
user: jwtDecode(parts[1]),
}
} catch {
// Ignore errors - bearer token is not a JWT, probably not intended for us
Expand Down
30 changes: 30 additions & 0 deletions tests/integration/commands/dev/dev-miscellaneous.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Buffer } from 'buffer'
import path from 'path'
import { fileURLToPath } from 'url'

Expand Down Expand Up @@ -151,6 +152,35 @@ describe.concurrent('commands/dev-miscellaneous', () => {
})
})

test('function clientContext.custom.netlify should be set', async (t) => {
await withSiteBuilder('site-with-function', async (builder) => {
await builder
.withNetlifyToml({ config: { functions: { directory: 'functions' } } })
.withFunction({
path: 'hello.js',
handler: async (_, context) => ({
statusCode: 200,
body: JSON.stringify(context),
}),
})
.buildAsync()

await withDevServer({ cwd: builder.directory }, async (server) => {
const response = await fetch(`${server.url}/.netlify/functions/hello`, {
headers: {
Authorization:
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb3VyY2UiOiJuZXRsaWZ5IGRldiIsInRlc3REYXRhIjoiTkVUTElGWV9ERVZfTE9DQUxMWV9FTVVMQVRFRF9JREVOVElUWSJ9.2eSDqUOZAOBsx39FHFePjYj12k0LrxldvGnlvDu3GMI',
},
}).then((res) => res.json())

const netlifyContext = Buffer.from(response.clientContext.custom.netlify, 'base64').toString()
t.expect(JSON.parse(netlifyContext).identity.url).toEqual(
'https://netlify-dev-locally-emulated-identity.netlify.com/.netlify/identity',
)
})
})
})

test('should enforce role based redirects with default secret and role path', async (t) => {
await withSiteBuilder('site-with-default-role-based-redirects', async (builder) => {
setupRoleBasedRedirectsSite(builder)
Expand Down
Loading