netlify-cli 8.15.4 → 8.15.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
- "version": "8.15.4",
3
+ "version": "8.15.5",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "netlify-cli",
9
- "version": "8.15.4",
9
+ "version": "8.15.5",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
@@ -15,7 +15,7 @@
15
15
  "@netlify/framework-info": "^9.0.0",
16
16
  "@netlify/local-functions-proxy": "^1.1.1",
17
17
  "@netlify/plugin-edge-handlers": "^3.0.4",
18
- "@netlify/plugins-list": "^6.6.0",
18
+ "@netlify/plugins-list": "^6.7.0",
19
19
  "@netlify/routing-local-proxy": "^0.34.1",
20
20
  "@netlify/zip-it-and-ship-it": "^5.5.2",
21
21
  "@octokit/rest": "^18.0.0",
@@ -2911,9 +2911,9 @@
2911
2911
  }
2912
2912
  },
2913
2913
  "node_modules/@netlify/plugins-list": {
2914
- "version": "6.6.0",
2915
- "resolved": "https://registry.npmjs.org/@netlify/plugins-list/-/plugins-list-6.6.0.tgz",
2916
- "integrity": "sha512-JaRh4NO4k5c7GfwJPVySAXhX7VO0zj23DNr4chVyh/q7q/jNZGsUQcvHfM6OyT3zWFlDjb5BrEf4CKFGYt8g5A==",
2914
+ "version": "6.7.0",
2915
+ "resolved": "https://registry.npmjs.org/@netlify/plugins-list/-/plugins-list-6.7.0.tgz",
2916
+ "integrity": "sha512-5+KKvsfg+lWiwQddLCNPv7pL1CiwKIT0M1GE8RuIokAq8DE+c8Ug2PC7seslRM5C5gGQiv60MfCpiFuwY6diQg==",
2917
2917
  "engines": {
2918
2918
  "node": "^12.20.0 || ^14.14.0 || >=16.0.0"
2919
2919
  }
@@ -23633,9 +23633,9 @@
23633
23633
  }
23634
23634
  },
23635
23635
  "@netlify/plugins-list": {
23636
- "version": "6.6.0",
23637
- "resolved": "https://registry.npmjs.org/@netlify/plugins-list/-/plugins-list-6.6.0.tgz",
23638
- "integrity": "sha512-JaRh4NO4k5c7GfwJPVySAXhX7VO0zj23DNr4chVyh/q7q/jNZGsUQcvHfM6OyT3zWFlDjb5BrEf4CKFGYt8g5A=="
23636
+ "version": "6.7.0",
23637
+ "resolved": "https://registry.npmjs.org/@netlify/plugins-list/-/plugins-list-6.7.0.tgz",
23638
+ "integrity": "sha512-5+KKvsfg+lWiwQddLCNPv7pL1CiwKIT0M1GE8RuIokAq8DE+c8Ug2PC7seslRM5C5gGQiv60MfCpiFuwY6diQg=="
23639
23639
  },
23640
23640
  "@netlify/routing-local-proxy": {
23641
23641
  "version": "0.34.1",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
3
  "description": "Netlify command line tool",
4
- "version": "8.15.4",
4
+ "version": "8.15.5",
5
5
  "author": "Netlify Inc.",
6
6
  "contributors": [
7
7
  "Mathias Biilmann <matt@netlify.com> (https://twitter.com/biilmann)",
@@ -82,7 +82,7 @@
82
82
  "@netlify/framework-info": "^9.0.0",
83
83
  "@netlify/local-functions-proxy": "^1.1.1",
84
84
  "@netlify/plugin-edge-handlers": "^3.0.4",
85
- "@netlify/plugins-list": "^6.6.0",
85
+ "@netlify/plugins-list": "^6.7.0",
86
86
  "@netlify/routing-local-proxy": "^0.34.1",
87
87
  "@netlify/zip-it-and-ship-it": "^5.5.2",
88
88
  "@octokit/rest": "^18.0.0",
@@ -136,6 +136,7 @@
136
136
  "is-plain-obj": "^3.0.0",
137
137
  "is-wsl": "^2.2.0",
138
138
  "isexe": "^2.0.0",
139
+ "jsonwebtoken": "^8.5.1",
139
140
  "jwt-decode": "^3.0.0",
140
141
  "lambda-local": "2.0.1",
141
142
  "listr": "^0.14.3",
@@ -197,7 +198,6 @@
197
198
  "graphviz": "^0.0.9",
198
199
  "husky": "^7.0.4",
199
200
  "ini": "^2.0.0",
200
- "jsonwebtoken": "^8.5.1",
201
201
  "mock-fs": "^5.1.2",
202
202
  "p-timeout": "^4.0.0",
203
203
  "proxyquire": "^2.1.3",
@@ -22,6 +22,7 @@ const {
22
22
  detectServerSettings,
23
23
  error,
24
24
  exit,
25
+ generateAuthlifyJWT,
25
26
  getSiteInformation,
26
27
  injectEnvVariables,
27
28
  log,
@@ -253,7 +254,29 @@ const dev = async (options, command) => {
253
254
  )
254
255
  }
255
256
 
256
- await injectEnvVariables({ env: command.netlify.cachedConfig.env, site })
257
+ const startNetlifyGraphWatcher = Boolean(options.graph)
258
+ let authlifyJWT
259
+
260
+ if (startNetlifyGraphWatcher) {
261
+ const netlifyToken = await command.authenticate()
262
+ authlifyJWT = generateAuthlifyJWT(netlifyToken, siteInfo.authlify_token_id, site.id)
263
+ }
264
+
265
+ await injectEnvVariables({
266
+ env: Object.assign(
267
+ command.netlify.cachedConfig.env,
268
+ authlifyJWT == null
269
+ ? {}
270
+ : {
271
+ ONEGRAPH_AUTHLIFY_TOKEN: {
272
+ sources: ['general'],
273
+ value: authlifyJWT,
274
+ },
275
+ },
276
+ ),
277
+ site,
278
+ })
279
+
257
280
  const { addonsUrls, capabilities, siteUrl, timeouts } = await getSiteInformation({
258
281
  // inherited from base command --offline
259
282
  offline: options.offline,
@@ -273,8 +296,26 @@ const dev = async (options, command) => {
273
296
 
274
297
  command.setAnalyticsPayload({ projectType: settings.framework || 'custom', live: options.live })
275
298
 
299
+ let configWithAuthlify
300
+
301
+ if (siteInfo.authlify_token_id) {
302
+ const netlifyToken = command.authenticate()
303
+ // Only inject the authlify config if a token ID exists. This prevents
304
+ // calling command.authenticate() (which opens a browser window) if the
305
+ // user hasn't enabled API Authentication
306
+ configWithAuthlify = Object.assign(config, {
307
+ authlify: {
308
+ netlifyToken,
309
+ authlifyTokenId: siteInfo.authlify_token_id,
310
+ siteId: site.id,
311
+ },
312
+ })
313
+ } else {
314
+ configWithAuthlify = config
315
+ }
316
+
276
317
  await startFunctionsServer({
277
- config,
318
+ config: configWithAuthlify,
278
319
  settings,
279
320
  site,
280
321
  siteUrl,
@@ -295,8 +336,6 @@ const dev = async (options, command) => {
295
336
  process.env.URL = url
296
337
  process.env.DEPLOY_URL = url
297
338
 
298
- const startNetlifyGraphWatcher = Boolean(options.graph)
299
-
300
339
  if (startNetlifyGraphWatcher && options.offline) {
301
340
  warn(`Unable to start Netlify Graph in offline mode`)
302
341
  } else if (startNetlifyGraphWatcher && !site.id) {
@@ -6,6 +6,7 @@ const {
6
6
  NETLIFYDEVERR,
7
7
  NETLIFYDEVLOG,
8
8
  error: errorExit,
9
+ generateAuthlifyJWT,
9
10
  getInternalFunctionsDir,
10
11
  log,
11
12
  } = require('../../utils')
@@ -44,7 +45,7 @@ const buildClientContext = function (headers) {
44
45
  }
45
46
  }
46
47
 
47
- const createHandler = function ({ functionsRegistry }) {
48
+ const createHandler = function ({ config, functionsRegistry }) {
48
49
  return async function handler(request, response) {
49
50
  // handle proxies without path re-writes (http-servr)
50
51
  const cleanPath = request.path.replace(/^\/.netlify\/(functions|builders)/, '')
@@ -105,6 +106,11 @@ const createHandler = function ({ functionsRegistry }) {
105
106
  rawQuery,
106
107
  }
107
108
 
109
+ if (config && config.authlify && config.authlify.authlifyTokenId != null) {
110
+ const { authlifyTokenId, netlifyToken, siteId } = config.authlify
111
+ event.authlifyToken = generateAuthlifyJWT(netlifyToken, authlifyTokenId, siteId)
112
+ }
113
+
108
114
  const clientContext = buildClientContext(request.headers) || {}
109
115
 
110
116
  if (func.isBackground) {
@@ -154,14 +160,14 @@ const createHandler = function ({ functionsRegistry }) {
154
160
  }
155
161
  }
156
162
 
157
- const getFunctionsServer = function ({ buildersPrefix, functionsPrefix, functionsRegistry, siteUrl }) {
163
+ const getFunctionsServer = function ({ buildersPrefix, config, functionsPrefix, functionsRegistry, siteUrl }) {
158
164
  // performance optimization, load express on demand
159
165
  // eslint-disable-next-line node/global-require
160
166
  const express = require('express')
161
167
  // eslint-disable-next-line node/global-require
162
168
  const expressLogging = require('express-logging')
163
169
  const app = express()
164
- const functionHandler = createHandler({ functionsRegistry })
170
+ const functionHandler = createHandler({ config, functionsRegistry })
165
171
 
166
172
  app.set('query parser', 'simple')
167
173
 
@@ -218,6 +224,7 @@ const startFunctionsServer = async ({
218
224
  await functionsRegistry.scan(functionsDirectories)
219
225
 
220
226
  const server = getFunctionsServer({
227
+ config,
221
228
  functionsRegistry,
222
229
  siteUrl,
223
230
  functionsPrefix,
package/src/utils/dev.js CHANGED
@@ -3,6 +3,7 @@ const process = require('process')
3
3
 
4
4
  const { get } = require('dot-prop')
5
5
  const getPort = require('get-port')
6
+ const jwt = require('jsonwebtoken')
6
7
  const isEmpty = require('lodash/isEmpty')
7
8
 
8
9
  const { supportsBackgroundFunctions } = require('../lib/account')
@@ -193,8 +194,30 @@ const acquirePort = async ({ configuredPort, defaultPort, errorMessage }) => {
193
194
  return acquiredPort
194
195
  }
195
196
 
197
+ // Generates an Authlify JWT with the following claims:
198
+ // - site_id
199
+ // - netlify_token -- the bearer token for the Netlify API
200
+ // - authlify_token_id -- the authlify token ID stored for the site after
201
+ // enabling API Authentication.
202
+ const generateAuthlifyJWT = (netlifyToken, authlifyTokenId, siteId) => {
203
+ const claims = {
204
+ netlify_token: netlifyToken,
205
+ authlify_token_id: authlifyTokenId,
206
+ site_id: siteId,
207
+ }
208
+
209
+ return jwt.sign(
210
+ { 'https://netlify.com/jwt/claims': claims },
211
+ // doesn't matter. OneGraph doesn't check the signature. The presence of
212
+ // the Netlify API bearer token is enough because we've authenticated the
213
+ // user through `command.authenticate()`
214
+ 'NOT_SIGNED',
215
+ )
216
+ }
217
+
196
218
  module.exports = {
197
219
  getSiteInformation,
198
220
  injectEnvVariables,
199
221
  acquirePort,
222
+ generateAuthlifyJWT,
200
223
  }