From c896c782bad3468d2d3246654de234141165cf7f Mon Sep 17 00:00:00 2001 From: neirac Date: Mon, 13 Apr 2026 15:29:19 -0400 Subject: [PATCH 01/25] accesskeys: add per-bucket scope to create, update, list, get Accept an optional scope parameter when creating or updating access keys. The scope restricts the key to specific buckets with configurable permission levels (read, readwrite, full). Create: POST /:account/accesskeys with scope parameter Accepts full envelope {version,permissions} or shorthand array [{bucket,level},...]. Validates structure, bucket names (1-63 chars), permission levels, and max 1000 entries. Update: POST /:account/accesskeys/:id with scope parameter Replaces the scope. An empty string removes the scope entirely, making the key unrestricted again. List/Get: translateAccessKey now returns scope as a parsed JSON object. When absent, scope is null (unrestricted key). node-ufds addAccessKey and updateAccessKey already pass through arbitrary attributes to UFDS, so no changes needed there. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/endpoints/accesskeys.js | 198 ++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 0dd7e68e..59bcbada 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -31,6 +31,149 @@ var InternalError = restify.InternalError; */ var MAX_KEYS = 100; +/** + * @brief Maximum bucket scope entries per access key + * + * Bounds Redis and UFDS storage per key. Validated at + * UFDS schema layer but also checked here for early + * rejection. + * + * @since 2.2.0 + */ +var MAX_SCOPE_ENTRIES = 1000; + +var VALID_SCOPE_LEVELS = ['read', 'readwrite', 'full']; + +/** + * @brief Validate a scope parameter from the request + * + * Accepts either the full JSON object or a shorthand + * array of {bucket, level} entries. Returns the + * canonical JSON string or null if invalid. + * + * Time complexity: O(n) where n = permissions count + * Space complexity: O(1) beyond the parsed object + * + * @param {string|Array|Object} input - Scope parameter + * @return {Object} {valid: bool, scope: string|null, + * error: string|null} + */ +function validateScope(input) { + var scope; + + if (typeof input === 'string') { + try { + scope = JSON.parse(input); + } catch (e) { + return { + valid: false, + scope: null, + error: 'scope: invalid JSON' + }; + } + } else { + scope = input; + } + + /* + * Accept shorthand array: [{bucket, level}, ...] + * and wrap it in the canonical envelope. + */ + if (Array.isArray(scope)) { + scope = { version: 1, permissions: scope }; + } + + if (!scope || typeof scope !== 'object') { + return { + valid: false, + scope: null, + error: 'scope: must be an object or array' + }; + } + + if (scope.version !== undefined && scope.version !== 1) { + return { + valid: false, + scope: null, + error: 'scope: version must be 1' + }; + } + scope.version = 1; + + if (!Array.isArray(scope.permissions)) { + return { + valid: false, + scope: null, + error: 'scope: permissions must be an array' + }; + } + + if (scope.permissions.length === 0) { + return { + valid: false, + scope: null, + error: 'scope: permissions array is empty' + }; + } + + if (scope.permissions.length > MAX_SCOPE_ENTRIES) { + return { + valid: false, + scope: null, + error: 'scope: exceeds maximum of ' + + MAX_SCOPE_ENTRIES + ' entries' + }; + } + + for (var i = 0; i < scope.permissions.length; i++) { + var p = scope.permissions[i]; + if (!p || typeof p !== 'object') { + return { + valid: false, + scope: null, + error: 'scope: permissions[' + i + + '] must be an object' + }; + } + if (typeof p.bucket !== 'string' || + p.bucket.length < 1 || + p.bucket.length > 63) { + return { + valid: false, + scope: null, + error: 'scope: permissions[' + i + + '].bucket must be 1-63 characters' + }; + } + if (VALID_SCOPE_LEVELS.indexOf(p.level) === -1) { + return { + valid: false, + scope: null, + error: 'scope: permissions[' + i + + '].level must be one of: ' + + VALID_SCOPE_LEVELS.join(', ') + }; + } + } + + return { + valid: true, + scope: JSON.stringify(scope), + error: null + }; +} + + +/** + * @brief Translate UFDS access key to API response format + * + * Maps internal UFDS attributes to the external API + * representation. Includes the accesskeyscope field + * as a parsed JSON object when present. + * + * @param {Object} accesskey - UFDS access key entry + * @return {Object} Translated access key for response + */ function translateAccessKey(accesskey) { if (!accesskey) { return {}; @@ -65,6 +208,22 @@ function translateAccessKey(accesskey) { translated.expiration = null; } + /* + * Return bucket scope as a parsed JSON object so + * callers can inspect permissions directly. When + * absent the key is unrestricted. + */ + if (accesskey.accesskeyscope) { + try { + translated.scope = + JSON.parse(accesskey.accesskeyscope); + } catch (e) { + translated.scope = null; + } + } else { + translated.scope = null; + } + return translated; } @@ -107,6 +266,24 @@ function create(req, res, next) { return; } + /* + * Per-bucket access key scoping. The scope parameter + * accepts either the full envelope: + * {"version":1,"permissions":[{bucket,level},...]} + * or the shorthand array: + * [{bucket,level},...] + * + * An empty/null scope means unrestricted (no scope). + */ + if (req.params.scope) { + var result = validateScope(req.params.scope); + if (!result.valid) { + next(new InvalidArgumentError(result.error)); + return; + } + params.accesskeyscope = result.scope; + } + try { vasync.waterfall([ @@ -354,6 +531,27 @@ function update(req, res, next) { params.description = req.params.description; } + /* + * Update bucket scope. An empty string removes the + * scope (makes the key unrestricted again). A non- + * empty value replaces the scope. + */ + if (req.params.scope !== undefined) { + if (req.params.scope === '' || + req.params.scope === null) { + /* Remove scope: set null so UFDS deletes attr */ + params.accesskeyscope = null; + } else { + var scopeResult = validateScope(req.params.scope); + if (!scopeResult.valid) { + next(new InvalidArgumentError( + scopeResult.error)); + return; + } + params.accesskeyscope = scopeResult.scope; + } + } + // Make it clear that credential type and expiration cannot be changed. if (req.params.credentialtype) { next(new ForbiddenError('credentialtype cannot be set via CloudAPI')); From cb7538988e3a34bf11a149c1507141f2e19cc367 Mon Sep 17 00:00:00 2001 From: neirac Date: Sat, 18 Apr 2026 21:25:31 -0400 Subject: [PATCH 02/25] fix: scope JSON size limit, HTTP 200 for updates - Add 50KB max scope JSON size validation in validateScope() - Fix update endpoint to return HTTP 200 (not 201) for modifications Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/endpoints/accesskeys.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 59bcbada..ade9776b 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -125,6 +125,16 @@ function validateScope(input) { }; } + // Guard against oversized scope JSON (max ~50KB) + var scopeJson = JSON.stringify(scope); + if (scopeJson.length > 51200) { + return { + valid: false, + scope: null, + error: 'scope: JSON exceeds 50KB size limit' + }; + } + for (var i = 0; i < scope.permissions.length; i++) { var p = scope.permissions[i]; if (!p || typeof p !== 'object') { @@ -158,7 +168,7 @@ function validateScope(input) { return { valid: true, - scope: JSON.stringify(scope), + scope: scopeJson, error: null }; } @@ -600,7 +610,7 @@ function update(req, res, next) { } log.debug('POST %s => %j', req.path(), accesskey); - res.send(201, accesskey); + res.send(200, accesskey); next(); return; }); From 0ef966caee6214f585ceb90d43e09cb605a15189 Mon Sep 17 00:00:00 2001 From: neirac Date: Sun, 19 Apr 2026 15:49:56 -0400 Subject: [PATCH 03/25] style: rename unused catch vars to _e for eslint compliance Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/endpoints/accesskeys.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index ade9776b..f442fdcb 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -6,7 +6,7 @@ /* * Copyright 2020 Joyent, Inc. - * Copyright 2025 Edgecast Cloud LLC. + * Copyright 2026 Edgecast Cloud LLC. */ @@ -64,7 +64,7 @@ function validateScope(input) { if (typeof input === 'string') { try { scope = JSON.parse(input); - } catch (e) { + } catch (_e) { return { valid: false, scope: null, @@ -227,7 +227,7 @@ function translateAccessKey(accesskey) { try { translated.scope = JSON.parse(accesskey.accesskeyscope); - } catch (e) { + } catch (_e) { translated.scope = null; } } else { From fad80bd2123acb93ae7f8fc46efc156517f54437 Mon Sep 17 00:00:00 2001 From: neirac Date: Mon, 20 Apr 2026 21:07:26 -0400 Subject: [PATCH 04/25] per-bucket scope: canonical envelope only, wildcard validation Standardize validateScope to accept only the canonical envelope object {version:1, permissions:[...]}. Remove shorthand array auto-wrapping and JSON string parsing. Require version explicitly. Add wildcard position check rejecting non-trailing wildcards. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/endpoints/accesskeys.js | 69 +++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index f442fdcb..1a0c3684 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -47,58 +47,38 @@ var VALID_SCOPE_LEVELS = ['read', 'readwrite', 'full']; /** * @brief Validate a scope parameter from the request * - * Accepts either the full JSON object or a shorthand - * array of {bucket, level} entries. Returns the - * canonical JSON string or null if invalid. + * Accepts the canonical scope envelope: + * {"version":1,"permissions":[{bucket,level},...]} + * + * Returns the canonical JSON string or null if invalid. * * Time complexity: O(n) where n = permissions count * Space complexity: O(1) beyond the parsed object * - * @param {string|Array|Object} input - Scope parameter + * @param {Object} input - Scope envelope object * @return {Object} {valid: bool, scope: string|null, * error: string|null} */ function validateScope(input) { - var scope; - - if (typeof input === 'string') { - try { - scope = JSON.parse(input); - } catch (_e) { - return { - valid: false, - scope: null, - error: 'scope: invalid JSON' - }; - } - } else { - scope = input; - } - - /* - * Accept shorthand array: [{bucket, level}, ...] - * and wrap it in the canonical envelope. - */ - if (Array.isArray(scope)) { - scope = { version: 1, permissions: scope }; - } - - if (!scope || typeof scope !== 'object') { + if (!input || typeof input !== 'object' || + Array.isArray(input)) { return { valid: false, scope: null, - error: 'scope: must be an object or array' + error: 'scope: must be an object with' + + ' version and permissions fields' }; } - if (scope.version !== undefined && scope.version !== 1) { + var scope = input; + + if (scope.version !== 1) { return { valid: false, scope: null, error: 'scope: version must be 1' }; } - scope.version = 1; if (!Array.isArray(scope.permissions)) { return { @@ -155,6 +135,23 @@ function validateScope(input) { '].bucket must be 1-63 characters' }; } + /* + * Wildcard position check: '*' is only + * valid as the sole character or as the + * last character of the pattern. + */ + var starIdx = p.bucket.indexOf('*'); + if (starIdx !== -1 && + starIdx !== p.bucket.length - 1) { + return { + valid: false, + scope: null, + error: 'scope: permissions[' + i + + '].bucket: wildcard (*)' + + ' only allowed as last' + + ' character' + }; + } if (VALID_SCOPE_LEVELS.indexOf(p.level) === -1) { return { valid: false, @@ -277,13 +274,11 @@ function create(req, res, next) { } /* - * Per-bucket access key scoping. The scope parameter - * accepts either the full envelope: + * Per-bucket access key scoping. Scope must be the + * canonical envelope: * {"version":1,"permissions":[{bucket,level},...]} - * or the shorthand array: - * [{bucket,level},...] * - * An empty/null scope means unrestricted (no scope). + * Absent/null scope means unrestricted. */ if (req.params.scope) { var result = validateScope(req.params.scope); From 8f7fcf4a1ea27b27cf554ea901a446c39572d884 Mon Sep 17 00:00:00 2001 From: neirac Date: Tue, 21 Apr 2026 09:38:06 -0400 Subject: [PATCH 05/25] scope: delegate validation to shared scope-schema module Replace inline validateScope() with delegation to scopeSchema.validateScope() from node-mahi. Remove local MAX_SCOPE_ENTRIES and VALID_SCOPE_LEVELS constants. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/endpoints/accesskeys.js | 128 ++---------------------------------- 1 file changed, 4 insertions(+), 124 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 1a0c3684..2f7282b8 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -17,6 +17,7 @@ var assert = require('assert-plus'); var restify = require('restify'); var resources = require('../resources'); +var scopeSchema = require('mahi').scopeSchema; var sprintf = util.format; @@ -31,27 +32,13 @@ var InternalError = restify.InternalError; */ var MAX_KEYS = 100; -/** - * @brief Maximum bucket scope entries per access key - * - * Bounds Redis and UFDS storage per key. Validated at - * UFDS schema layer but also checked here for early - * rejection. - * - * @since 2.2.0 - */ -var MAX_SCOPE_ENTRIES = 1000; - -var VALID_SCOPE_LEVELS = ['read', 'readwrite', 'full']; - /** * @brief Validate a scope parameter from the request * - * Accepts the canonical scope envelope: + * Delegates to the canonical scope schema module in + * node-mahi. Accepts only the canonical envelope: * {"version":1,"permissions":[{bucket,level},...]} * - * Returns the canonical JSON string or null if invalid. - * * Time complexity: O(n) where n = permissions count * Space complexity: O(1) beyond the parsed object * @@ -60,114 +47,7 @@ var VALID_SCOPE_LEVELS = ['read', 'readwrite', 'full']; * error: string|null} */ function validateScope(input) { - if (!input || typeof input !== 'object' || - Array.isArray(input)) { - return { - valid: false, - scope: null, - error: 'scope: must be an object with' + - ' version and permissions fields' - }; - } - - var scope = input; - - if (scope.version !== 1) { - return { - valid: false, - scope: null, - error: 'scope: version must be 1' - }; - } - - if (!Array.isArray(scope.permissions)) { - return { - valid: false, - scope: null, - error: 'scope: permissions must be an array' - }; - } - - if (scope.permissions.length === 0) { - return { - valid: false, - scope: null, - error: 'scope: permissions array is empty' - }; - } - - if (scope.permissions.length > MAX_SCOPE_ENTRIES) { - return { - valid: false, - scope: null, - error: 'scope: exceeds maximum of ' + - MAX_SCOPE_ENTRIES + ' entries' - }; - } - - // Guard against oversized scope JSON (max ~50KB) - var scopeJson = JSON.stringify(scope); - if (scopeJson.length > 51200) { - return { - valid: false, - scope: null, - error: 'scope: JSON exceeds 50KB size limit' - }; - } - - for (var i = 0; i < scope.permissions.length; i++) { - var p = scope.permissions[i]; - if (!p || typeof p !== 'object') { - return { - valid: false, - scope: null, - error: 'scope: permissions[' + i + - '] must be an object' - }; - } - if (typeof p.bucket !== 'string' || - p.bucket.length < 1 || - p.bucket.length > 63) { - return { - valid: false, - scope: null, - error: 'scope: permissions[' + i + - '].bucket must be 1-63 characters' - }; - } - /* - * Wildcard position check: '*' is only - * valid as the sole character or as the - * last character of the pattern. - */ - var starIdx = p.bucket.indexOf('*'); - if (starIdx !== -1 && - starIdx !== p.bucket.length - 1) { - return { - valid: false, - scope: null, - error: 'scope: permissions[' + i + - '].bucket: wildcard (*)' + - ' only allowed as last' + - ' character' - }; - } - if (VALID_SCOPE_LEVELS.indexOf(p.level) === -1) { - return { - valid: false, - scope: null, - error: 'scope: permissions[' + i + - '].level must be one of: ' + - VALID_SCOPE_LEVELS.join(', ') - }; - } - } - - return { - valid: true, - scope: scopeJson, - error: null - }; + return scopeSchema.validateScope(input); } From f754961c5c46716e20916bbff1a09ee6b63493d5 Mon Sep 17 00:00:00 2001 From: neirac Date: Wed, 22 Apr 2026 13:37:05 -0400 Subject: [PATCH 06/25] accesskeys: cache-push scoped keys to mahi Redis on create/update/delete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scoped access keys had a 2-10s replication delay (UFDS → replicator → Redis) before becoming usable for S3 requests. Add fire-and-forget cachePush() calls after UFDS writes so scoped keys are immediately available in Redis. The replicator remains the authoritative fallback. - create(): push scoped keys only (unscoped use UFDS read-through) - update(): push when scope or status changes on scoped keys - del(): scopeRevoke all keys (no scope info at delete time) - Bump node-mahi 2.3.3 → 2.5.0 for cachePush/scopeRevoke methods Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/endpoints/accesskeys.js | 81 +++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 2f7282b8..43a2a34e 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -217,6 +217,30 @@ function create(req, res, next) { var accesskeysecret = accesskey.accesskeysecret; + /* + * Fire-and-forget: push scoped key to mahi + * Redis for immediate availability (bypasses + * replicator delay). Best-effort — replicator + * is the authoritative fallback. + */ + if (req.sdc.mahi && params.accesskeyscope) { + req.sdc.mahi.cachePush({ + accesskeyid: accesskey.accesskeyid, + accesskeysecret: accesskeysecret, + ownerUuid: req.account.uuid, + status: 'Active', + scope: params.accesskeyscope + }, function (pushErr) { + if (pushErr) { + log.warn({err: pushErr, + accesskeyid: + accesskey.accesskeyid + }, 'cache-push best-effort' + + ' failed'); + } + }); + } + accesskey = translateAccessKey(accesskey); // Only return the accesskeysecret on creation @@ -379,6 +403,27 @@ function del(req, res, next) { return; } + /* + * Fire-and-forget: revoke key from mahi Redis + * immediately. Applies to all keys (not just + * scoped) because we don't have scope info at + * delete time without an extra UFDS read. + * Harmless no-op for unscoped keys. + */ + if (req.sdc.mahi) { + req.sdc.mahi.scopeRevoke( + req.params.accesskeyid, + function (revokeErr) { + if (revokeErr) { + log.warn({err: revokeErr, + accesskeyid: + req.params.accesskeyid + }, 'cache-revoke best-effort' + + ' failed'); + } + }); + } + log.debug('DELETE %s -> ok', req.path()); res.send(204); next(); @@ -457,6 +502,42 @@ function update(req, res, next) { return; } + /* + * Capture secret before translateAccessKey strips + * it. Fire cache-push when scope changes OR when + * status changes on a key that has a scope (so + * deactivation of a scoped key propagates to + * Redis immediately). + */ + var rawSecret = accesskey.accesskeysecret; + var hasScope = params.accesskeyscope !== undefined || + accesskey.accesskeyscope; + var scopeChanged = + params.accesskeyscope !== undefined; + var statusChanged = + params.status !== undefined; + + if (req.sdc.mahi && hasScope && + (scopeChanged || statusChanged)) { + req.sdc.mahi.cachePush({ + accesskeyid: params.accesskeyid, + accesskeysecret: rawSecret, + ownerUuid: req.account.uuid, + status: params.status || + accesskey.status || 'Active', + scope: scopeChanged + ? params.accesskeyscope + : (accesskey.accesskeyscope || null) + }, function (pushErr) { + if (pushErr) { + log.warn({err: pushErr, + accesskeyid: params.accesskeyid + }, 'cache-push best-effort' + + ' failed'); + } + }); + } + accesskey = translateAccessKey(accesskey); if (account) { diff --git a/package.json b/package.json index 5c38fdfb..ed7ce2c1 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "kang": "^1.3.0", "keyapi": "git+https://github.com/TritonDataCenter/keyapi.git#bedd6fe787a4f3f3942724b37baed19162c8f074", "krill": "1.0.1", - "mahi": "2.3.3", + "mahi": "2.5.0", "mime": "^1.6.0", "mooremachine": "^2.3.0", "nodemailer": "0.7.1", From 0c22b07cc547e082174b063c5bc396fd00a4a90b Mon Sep 17 00:00:00 2001 From: neirac Date: Wed, 22 Apr 2026 20:05:29 -0400 Subject: [PATCH 07/25] remove big O notation, adds no value --- lib/endpoints/accesskeys.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 43a2a34e..b55f9890 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -39,9 +39,6 @@ var MAX_KEYS = 100; * node-mahi. Accepts only the canonical envelope: * {"version":1,"permissions":[{bucket,level},...]} * - * Time complexity: O(n) where n = permissions count - * Space complexity: O(1) beyond the parsed object - * * @param {Object} input - Scope envelope object * @return {Object} {valid: bool, scope: string|null, * error: string|null} @@ -154,7 +151,7 @@ function create(req, res, next) { } /* - * Per-bucket access key scoping. Scope must be the + * Per-bucket access key scoping. Scope must be the * canonical envelope: * {"version":1,"permissions":[{bucket,level},...]} * From 880d1aa3b5948c1a78e44ecb2c0fab1e0e9eeffb Mon Sep 17 00:00:00 2001 From: neirac Date: Thu, 23 Apr 2026 15:40:49 -0400 Subject: [PATCH 08/25] fix: update package-lock.json for mahi 2.5.0 Sync lockfile with package.json mahi 2.5.0 dependency to fix Jenkins npm ci failure. Preserves lockfileVersion 1. Co-Authored-By: Claude Opus 4.6 (1M context) --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index d8adc986..8cb37fea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3469,11 +3469,11 @@ } }, "mahi": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/mahi/-/mahi-2.3.3.tgz", - "integrity": "sha512-WGJx0XMRAsJ7YP11ubQa0yonPMrSMqDa/n27Rwwf+xedP9S+hUzhXBNDERzXN2OpUD0j9gXfxlCS5ygTTrRrFA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/mahi/-/mahi-2.5.0.tgz", + "integrity": "sha512-16gnn8K0M+C6VreA82yq5AettunTSDURzc0TY4HtTk9rjX8AcT/wRApu/Iq2GynpihAiFC13mBdeamGYcn8xUQ==", "requires": { - "aperture": "git+https://github.com/joyent/node-aperture.git#516f54924f9b3c997cca674e92937250801bd037", + "aperture": "git+https://github.com/TritonDataCenter/node-aperture.git#3081d76351d44c7ab1f3d7966b6636c4053b80f8", "assert-plus": "0.1.5", "bunyan": "1.8.12", "http-signature": "0.10.0", @@ -3483,8 +3483,8 @@ }, "dependencies": { "aperture": { - "version": "git+https://github.com/joyent/node-aperture.git#516f54924f9b3c997cca674e92937250801bd037", - "from": "git+https://github.com/joyent/node-aperture.git#516f54924f9b3c997cca674e92937250801bd037", + "version": "git+https://github.com/TritonDataCenter/node-aperture.git#3081d76351d44c7ab1f3d7966b6636c4053b80f8", + "from": "git+https://github.com/TritonDataCenter/node-aperture.git#3081d76351d44c7ab1f3d7966b6636c4053b80f8", "requires": { "assert-plus": "1.0.0", "ipaddr.js": "0.1.1", From a18b2f016edbc607558bd29877a4e5a4da01fa31 Mon Sep 17 00:00:00 2001 From: neirac Date: Thu, 23 Apr 2026 15:40:49 -0400 Subject: [PATCH 09/25] fix: pin mahi to node-mahi git repo commit 62c2486 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The published mahi@2.5.0 on npm does not include scopeSchema, cachePush, or scopeRevoke — those exist only in the node-mahi repo. Pin to the git commit like manta-buckets-api does. Co-Authored-By: Claude Opus 4.6 (1M context) --- package-lock.json | 5 ++--- package.json | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8cb37fea..a4b87c8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3469,9 +3469,8 @@ } }, "mahi": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/mahi/-/mahi-2.5.0.tgz", - "integrity": "sha512-16gnn8K0M+C6VreA82yq5AettunTSDURzc0TY4HtTk9rjX8AcT/wRApu/Iq2GynpihAiFC13mBdeamGYcn8xUQ==", + "version": "git+https://github.com/TritonDataCenter/node-mahi.git#62c2486", + "from": "git+https://github.com/TritonDataCenter/node-mahi.git#62c2486", "requires": { "aperture": "git+https://github.com/TritonDataCenter/node-aperture.git#3081d76351d44c7ab1f3d7966b6636c4053b80f8", "assert-plus": "0.1.5", diff --git a/package.json b/package.json index ed7ce2c1..b570a5a4 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "kang": "^1.3.0", "keyapi": "git+https://github.com/TritonDataCenter/keyapi.git#bedd6fe787a4f3f3942724b37baed19162c8f074", "krill": "1.0.1", - "mahi": "2.5.0", + "mahi": "git+https://github.com/TritonDataCenter/node-mahi.git#62c2486", "mime": "^1.6.0", "mooremachine": "^2.3.0", "nodemailer": "0.7.1", From 13a468ad3780f92b13c0d5c467b670b08944c72c Mon Sep 17 00:00:00 2001 From: neirac Date: Fri, 24 Apr 2026 13:31:47 -0400 Subject: [PATCH 10/25] fix: cachePush all keys on create, not just scoped keys Previously only scoped keys were pushed to mahi Redis on creation. Unscoped keys relied solely on the UFDS replicator, leaving a 2-15s window where the key was not in Redis and auth would fail (since the UFDS read-through in sigv4 was dead due to the ufdsPool/ufds property name mismatch, now fixed in mahi). Push all keys on creation for immediate availability. The cost is one fire-and-forget HTTP POST per key creation; the benefit is eliminating the auth failure window for all keys, not just scoped ones. Co-Authored-By: Claude Sonnet 4.6 --- lib/endpoints/accesskeys.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index b55f9890..8d3789aa 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -215,18 +215,22 @@ function create(req, res, next) { var accesskeysecret = accesskey.accesskeysecret; /* - * Fire-and-forget: push scoped key to mahi - * Redis for immediate availability (bypasses + * Fire-and-forget: push key to mahi Redis + * for immediate availability (bypasses * replicator delay). Best-effort — replicator * is the authoritative fallback. + * + * Push ALL keys (not just scoped) so that + * newly created keys are usable immediately + * without waiting for UFDS→Redis replication. */ - if (req.sdc.mahi && params.accesskeyscope) { + if (req.sdc.mahi) { req.sdc.mahi.cachePush({ accesskeyid: accesskey.accesskeyid, accesskeysecret: accesskeysecret, ownerUuid: req.account.uuid, status: 'Active', - scope: params.accesskeyscope + scope: params.accesskeyscope || null }, function (pushErr) { if (pushErr) { log.warn({err: pushErr, From de31e7b36ff99542dbb6d5c4eae4a073e91823ee Mon Sep 17 00:00:00 2001 From: neirac Date: Fri, 24 Apr 2026 21:43:10 -0400 Subject: [PATCH 11/25] deps: pin node-ufds to git commit 4a765f2 (v1.9.2, idleTimeout fix) Co-Authored-By: Claude Sonnet 4.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b570a5a4..67b760ef 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "semver": "5.4.1", "triton-metrics": "1.0.3", "triton-netconfig": "1.5.0", - "ufds": "^1.9.1", + "ufds": "git+https://github.com/TritonDataCenter/node-ufds.git#4a765f2", "uuid": "^8.3.0", "uuid-by-string": "0.6.0", "vasync": "2.2.0", From 0ce714f3ee851ed54eeb3ed925c851bc178264a8 Mon Sep 17 00:00:00 2001 From: neirac Date: Fri, 24 Apr 2026 21:43:10 -0400 Subject: [PATCH 12/25] deps: pin node-ufds to git commit f8ea6ad (v1.9.2, idleTimeout fix) Co-Authored-By: Claude Sonnet 4.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 67b760ef..ff40fd3f 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "semver": "5.4.1", "triton-metrics": "1.0.3", "triton-netconfig": "1.5.0", - "ufds": "git+https://github.com/TritonDataCenter/node-ufds.git#4a765f2", + "ufds": "git+https://github.com/TritonDataCenter/node-ufds.git#f8ea6ad", "uuid": "^8.3.0", "uuid-by-string": "0.6.0", "vasync": "2.2.0", From 23357a8b910306442ac8c7b63f300abc5db982bf Mon Sep 17 00:00:00 2001 From: neirac Date: Fri, 24 Apr 2026 23:48:43 -0400 Subject: [PATCH 13/25] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ff40fd3f..94e97735 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cloudapi", "description": "Triton CloudAPI", - "version": "9.21.0", + "version": "9.21.1", "author": "Edgecast Cloud (edgecast.io)", "private": true, "engines": { From 2dd70d01497c5df4c42e12f7c94d669c0e5a8789 Mon Sep 17 00:00:00 2001 From: neirac Date: Sat, 25 Apr 2026 00:05:17 -0400 Subject: [PATCH 14/25] fix: regenerate package-lock.json for git-pinned node-ufds The stale lockfile pinned ufds to the npm registry version (1.6.1), overriding the git URL in package.json. npm install resolved the registry version instead of fetching commit f8ea6ad (v1.9.2) from GitHub. Regenerated with npm v6.4.1 on Node v6.17.1 to capture the git resolution. Co-Authored-By: Claude Sonnet 4.6 --- package-lock.json | 1728 ++++++++++++++++++--------------------------- 1 file changed, 698 insertions(+), 1030 deletions(-) diff --git a/package-lock.json b/package-lock.json index a4b87c8f..05df9b90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "cloudapi", - "version": "9.21.0", + "version": "9.21.1", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -24,13 +24,13 @@ } }, "@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "requires": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -55,37 +55,37 @@ "dev": true }, "@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "dev": true, "requires": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.0" } }, "@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" } }, "@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "dependencies": { @@ -97,13 +97,19 @@ "requires": { "ms": "^2.1.3" } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true } } }, "@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.27.1", @@ -222,16 +228,6 @@ "verror": "1.3.6" }, "dependencies": { - "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha512-g21Br4ELmVaKCVSUSSTXecKG+MiLcHFoby5RPPUmfZdhQTontXUOPf0QK/TvreRjgItRiyO928zxR4TCrnuwmA==" - }, - "json-schema": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", - "integrity": "sha512-DFzwwaFNKI+cfMyHtcyGA6N9d8jOWEtLc9IrT7WbpZc1V8M5S/HMBjJ3aM2Fx40bcTL2xTuIX/bBr8Zj2soGyg==" - }, "jsprim": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.5.1.tgz", @@ -317,14 +313,6 @@ "verror": "^1.10.0" }, "dependencies": { - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "requires": { - "nan": "^2.14.0" - } - }, "extsprintf": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz", @@ -457,9 +445,9 @@ "integrity": "sha512-dJG+f666ZYoqodStymR+Es0hE/yBGjaNv/1A/UqerflS/Krgzfv+AhyRNG4CDKlSuhpWHbbaVju8hzedyLz2Iw==" }, "brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -482,15 +470,6 @@ "safe-json-stringify": "~1" }, "dependencies": { - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, "moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -512,14 +491,14 @@ } }, "call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "dev": true, "requires": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" } }, @@ -626,16 +605,6 @@ "precond": "0.2" } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, - "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha512-g21Br4ELmVaKCVSUSSTXecKG+MiLcHFoby5RPPUmfZdhQTontXUOPf0QK/TvreRjgItRiyO928zxR4TCrnuwmA==" - }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -813,30 +782,11 @@ "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==", "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", "dev": true - }, - "verror": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - } - } } } }, @@ -917,9 +867,9 @@ "dev": true }, "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "cp-file": { "version": "6.2.0", @@ -1001,14 +951,10 @@ "verror": ">=1.6.1 <2.0.0" }, "dependencies": { - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } + "extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" }, "ipaddr.js": { "version": "1.9.1", @@ -1046,20 +992,11 @@ } }, "dashdash": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.7.3.tgz", - "integrity": "sha512-NxuWFXR3+HJULO6F6VprWnUQbx0MXgfEuOfz3m+pw8LYZV06SHRjcaBVvVlwH132xJq12mljySVDLcbMcFM7EA==", - "dev": true, + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "requires": { - "assert-plus": "0.1.x" - }, - "dependencies": { - "assert-plus": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==", - "dev": true - } + "assert-plus": "^1.0.0" } }, "data-view-buffer": { @@ -1096,12 +1033,11 @@ } }, "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } }, "decamelize": { @@ -1222,12 +1158,11 @@ } }, "dtrace-provider": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", - "integrity": "sha512-yqNrDWYWOR3wumcWPhlIGIKRSFMbDEwilGi+xYeaY4wW82cZrWsqGE+jsVnouxMqt/kCVsNmy/XDXLrm/J6SJg==", - "optional": true, + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", "requires": { - "nan": "^2.0.8" + "nan": "^2.14.0" } }, "dunder-proto": { @@ -1261,16 +1196,6 @@ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "requires": { "iconv-lite": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } } }, "error-ex": { @@ -1283,9 +1208,9 @@ } }, "es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", "dev": true, "requires": { "array-buffer-byte-length": "^1.0.2", @@ -1355,12 +1280,6 @@ "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } - }, - "object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true } } }, @@ -1468,10 +1387,33 @@ "text-table": "~0.2.0" }, "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true } } @@ -1515,9 +1457,9 @@ "dev": true }, "esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -1577,12 +1519,23 @@ "chardet": "^0.4.0", "iconv-lite": "^0.4.17", "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } } }, "extsprintf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", - "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha512-g21Br4ELmVaKCVSUSSTXecKG+MiLcHFoby5RPPUmfZdhQTontXUOPf0QK/TvreRjgItRiyO928zxR4TCrnuwmA==" }, "fast": { "version": "3.1.3", @@ -1606,14 +1559,15 @@ "verror": "^1.7.0" }, "dependencies": { - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } + "extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, "jsprim": { "version": "1.4.2", @@ -1735,6 +1689,31 @@ "graceful-fs": "^4.1.2", "rimraf": "~2.6.2", "write": "^0.2.1" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "follow-redirects": { @@ -1742,7 +1721,7 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.3.tgz", "integrity": "sha512-ZyO6tx9xafGe5n4SdO2CN+3Gmm0ntAc8YRyRaaDT4eNbE0eTv7rjLKJb3iGTtVJ/SHhPPHXWGGY5h21nMxJnbw==", "requires": { - "underscore": "^1.13.7" + "underscore": "^1.13.8" } }, "for-each": { @@ -2291,25 +2270,17 @@ "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "requires": { "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - } } }, "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "optional": true, "requires": { - "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", + "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -2415,9 +2386,9 @@ } }, "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", "requires": { "function-bind": "^1.1.2" } @@ -2466,12 +2437,11 @@ } }, "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "ignore": { @@ -2890,6 +2860,35 @@ "requires": { "ms": "^2.1.3" } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } } } }, @@ -2925,16 +2924,6 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==" }, - "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha512-g21Br4ELmVaKCVSUSSTXecKG+MiLcHFoby5RPPUmfZdhQTontXUOPf0QK/TvreRjgItRiyO928zxR4TCrnuwmA==" - }, - "json-schema": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", - "integrity": "sha512-DFzwwaFNKI+cfMyHtcyGA6N9d8jOWEtLc9IrT7WbpZc1V8M5S/HMBjJ3aM2Fx40bcTL2xTuIX/bBr8Zj2soGyg==" - }, "jsprim": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.5.1.tgz", @@ -2979,9 +2968,9 @@ "dev": true }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3006,9 +2995,9 @@ "dev": true }, "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", + "integrity": "sha512-DFzwwaFNKI+cfMyHtcyGA6N9d8jOWEtLc9IrT7WbpZc1V8M5S/HMBjJ3aM2Fx40bcTL2xTuIX/bBr8Zj2soGyg==" }, "json-schema-traverse": { "version": "0.3.1", @@ -3037,6 +3026,11 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" } } }, @@ -3058,6 +3052,11 @@ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, "jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -3123,14 +3122,6 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", "integrity": "sha512-g62n3Kb9cszeZvmvBUqP/dsEJD/+80pDA8u8KqHnAPrVnQ2Je9rVV6opxkhuWCd1kCn2gOibzDKxCtBvD3q5kA==" }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "requires": { - "assert-plus": "^1.0.0" - } - }, "extsprintf": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz", @@ -3221,16 +3212,6 @@ "verror": "1.3.6" }, "dependencies": { - "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha512-g21Br4ELmVaKCVSUSSTXecKG+MiLcHFoby5RPPUmfZdhQTontXUOPf0QK/TvreRjgItRiyO928zxR4TCrnuwmA==" - }, - "json-schema": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", - "integrity": "sha512-DFzwwaFNKI+cfMyHtcyGA6N9d8jOWEtLc9IrT7WbpZc1V8M5S/HMBjJ3aM2Fx40bcTL2xTuIX/bBr8Zj2soGyg==" - }, "jsprim": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.5.1.tgz", @@ -3318,16 +3299,20 @@ "assert-plus": "0.1.x" } }, + "dtrace-provider": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", + "integrity": "sha512-yqNrDWYWOR3wumcWPhlIGIKRSFMbDEwilGi+xYeaY4wW82cZrWsqGE+jsVnouxMqt/kCVsNmy/XDXLrm/J6SJg==", + "optional": true, + "requires": { + "nan": "^2.0.8" + } + }, "extsprintf": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.0.tgz", "integrity": "sha512-AtBFy+ysvNodhorg/XoW8l+3VtfhILEWc53shEOsAuyDQTnQoXDfI2x9c93QY+RMdCQWAbL0XqpidgJe3BOCFA==" }, - "json-schema": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", - "integrity": "sha512-DFzwwaFNKI+cfMyHtcyGA6N9d8jOWEtLc9IrT7WbpZc1V8M5S/HMBjJ3aM2Fx40bcTL2xTuIX/bBr8Zj2soGyg==" - }, "jsprim": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.3.0.tgz", @@ -3419,9 +3404,9 @@ } }, "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==" }, "lodash.flattendeep": { "version": "4.4.0", @@ -3469,7 +3454,7 @@ } }, "mahi": { - "version": "git+https://github.com/TritonDataCenter/node-mahi.git#62c2486", + "version": "git+https://github.com/TritonDataCenter/node-mahi.git#62c2486849ed0b93cf5767905731017e756ae587", "from": "git+https://github.com/TritonDataCenter/node-mahi.git#62c2486", "requires": { "aperture": "git+https://github.com/TritonDataCenter/node-aperture.git#3081d76351d44c7ab1f3d7966b6636c4053b80f8", @@ -3487,7 +3472,7 @@ "requires": { "assert-plus": "1.0.0", "ipaddr.js": "0.1.1", - "jsprim": "0.5.1", + "jsprim": "2.0.2", "moment": "2.3.1", "verror": "1.3.6" }, @@ -3531,38 +3516,11 @@ } } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, "ctype": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz", "integrity": "sha512-C+CbWLSk0xdPcp7evo2YEF0o8SLKcDCQsw//accyrf8/NAWYzmUhmL8ZiSokvuwwMQ08RK10U9pkRcyy8EmA5A==" }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, - "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha512-g21Br4ELmVaKCVSUSSTXecKG+MiLcHFoby5RPPUmfZdhQTontXUOPf0QK/TvreRjgItRiyO928zxR4TCrnuwmA==" - }, "http-signature": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.0.tgz", @@ -3580,49 +3538,6 @@ } } }, - "json-schema": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", - "integrity": "sha512-DFzwwaFNKI+cfMyHtcyGA6N9d8jOWEtLc9IrT7WbpZc1V8M5S/HMBjJ3aM2Fx40bcTL2xTuIX/bBr8Zj2soGyg==" - }, - "jsprim": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.5.1.tgz", - "integrity": "sha512-NC8/NMMXIQOn4BczQMPZBrp66oIcUNNf5ajhhe4s7rEfugRzyxpwFddiMUHRER119Q6JyRoYO+pvAyTaS+OBwA==", - "requires": { - "extsprintf": "1.0.2", - "json-schema": "0.2.2", - "verror": "1.3.6" - }, - "dependencies": { - "verror": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", - "integrity": "sha512-i8GFYwImt5D5B8CPpi2jrDTy/faq4OEW+NkOTLSKcIdPfdYJvWv3VZddDKl0ByvBe6cJ2s5Mm2XDtv5c2pj/Eg==", - "requires": { - "extsprintf": "1.0.2" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==" - }, - "qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "requires": { - "side-channel": "^1.1.0" - } - }, "restify": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/restify/-/restify-4.3.4.tgz", @@ -3694,19 +3609,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", "integrity": "sha512-IrpJ+yoG4EOH8DFWuVg+8H1kW1Oaof0Wxe7cPcXW3x9BjkN/eVo54F15LyqemnDIUYskQWr9qvl/RihmSy6+xQ==" }, - "spdy": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", - "integrity": "sha512-jEvgkLRpMza5GON0oDzvLTLMAVfB5BxeOPbsWyisEyE8IbxL6cCiKbr8xrJdScs6XoOUp7pQy4PI+GVczHbO4w==", - "requires": { - "debug": "^2.6.8", - "handle-thing": "^1.2.5", - "http-deceiver": "^1.2.7", - "safe-buffer": "^5.0.1", - "select-hose": "^2.0.0", - "spdy-transport": "^2.0.18" - } - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -3839,9 +3741,9 @@ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "requires": { "brace-expansion": "^1.1.7" } @@ -3914,15 +3816,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", "integrity": "sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw==" - }, - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } } } }, @@ -3945,6 +3838,16 @@ "verror": "^1.9.0" }, "dependencies": { + "extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, "jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -3971,10 +3874,9 @@ } }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "mute-stream": { "version": "0.0.7", @@ -3991,36 +3893,12 @@ "mkdirp": "~0.5.1", "ncp": "~2.0.0", "rimraf": "~2.4.0" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", - "optional": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", - "optional": true, - "requires": { - "glob": "^6.0.1" - } - } } }, "nan": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", - "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==" + "version": "2.26.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.26.2.tgz", + "integrity": "sha512-0tTvBTYkt3tdGw22nrAy50x7gpbGCCFH3AFcyS5WiUu7Eu4vWlri1woE6qHBSfy11vksDqkiwjOnlR7WV8G1Hw==" }, "natural-compare": { "version": "1.4.0", @@ -4035,10 +3913,9 @@ "optional": true }, "negotiator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz", - "integrity": "sha512-oXmnazqehLNFohqgLxRyUdOQU9/UX0NpCpsnbjWUjM62ZM8oSOXYZpHc68XR130ftPNano0oQXGdREAplZRhaQ==", - "dev": true + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==" }, "nested-error-stacks": { "version": "2.1.1", @@ -4056,12 +3933,6 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.9.0.tgz", "integrity": "sha512-zLcTg6P4AbcHPq465ZMFNXx7XpKKJh+7kkN699NiQWisR2uWYOWNWqRHAmbnmKiL4e9aLSlmy5U7rEMUXV59+A==" }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==", - "dev": true - }, "nodemailer": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-0.7.1.tgz", @@ -4120,14 +3991,6 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } } }, "nyc": { @@ -4163,12 +4026,35 @@ "yargs-parser": "^13.0.0" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -4184,10 +4070,9 @@ "dev": true }, "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" }, "object-is": { "version": "1.1.6", @@ -4444,10 +4329,12 @@ "integrity": "sha512-h/vscxLPvI2l7k/0dFUKZ5I5TgMCJ/Pl+J6rw77PDuQM6UApf/GaRVkjv/YSm2k+fbp7Yw8dxsoe29DolT7h7w==" }, "qs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-3.1.0.tgz", - "integrity": "sha512-nR5uYqNsm8CgBhfCpsYKz6iDhvKjf0xdFT4KanNlLP40COGwZEsjbLoDyL9VrTXyiICUGUbsiN3gBpLGZhSZWQ==", - "dev": true + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "requires": { + "side-channel": "^1.1.0" + } }, "rai": { "version": "0.1.12", @@ -4487,6 +4374,13 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "reflect.getprototypeof": { @@ -4557,11 +4451,12 @@ } }, "resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, "requires": { + "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" @@ -4610,23 +4505,6 @@ "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", "integrity": "sha512-T6CEkoSV4q50zW3TlTHMbzy1E5+zlnNcY+yb7tWVYlTwPhx9LpnfAkd4wecpWknDyptp4k97LUZeInlf6jdzBg==" }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, "extsprintf": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz", @@ -4642,42 +4520,11 @@ "ctype": "0.5.3" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==" - }, - "qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "requires": { - "side-channel": "^1.1.0" - } - }, "semver": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", "integrity": "sha512-IrpJ+yoG4EOH8DFWuVg+8H1kW1Oaof0Wxe7cPcXW3x9BjkN/eVo54F15LyqemnDIUYskQWr9qvl/RihmSy6+xQ==" }, - "spdy": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", - "integrity": "sha512-jEvgkLRpMza5GON0oDzvLTLMAVfB5BxeOPbsWyisEyE8IbxL6cCiKbr8xrJdScs6XoOUp7pQy4PI+GVczHbO4w==", - "requires": { - "debug": "^2.6.8", - "handle-thing": "^1.2.5", - "http-deceiver": "^1.2.7", - "safe-buffer": "^5.0.1", - "select-hose": "^2.0.0", - "spdy-transport": "^2.0.18" - } - }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -4724,15 +4571,6 @@ "uuid": "^3.0.1" }, "dependencies": { - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -4795,12 +4633,12 @@ "integrity": "sha512-RgncoxLF1GqwAzTZs/K2YpZkWrdIYbXsmesdomi+iPilSzjUyr/wzNIuteoTVaWokzdwZIJ9NHRNQa/RUiOB2g==" }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "optional": true, "requires": { - "glob": "^7.1.3" + "glob": "^6.0.1" } }, "run-async": { @@ -4825,14 +4663,14 @@ } }, "safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", "dev": true, "requires": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, @@ -4846,9 +4684,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-json-stringify": { "version": "1.2.0", @@ -4929,43 +4767,11 @@ "verror": "^1.6.0" }, "dependencies": { - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, "clone": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/clone/-/clone-0.1.8.tgz", "integrity": "sha512-HBjIyGuJYe0BA0arOXCK6MH9R9cbMIMPPOi/T5E52mfdN2UfqdblzFgrg873hRvX3aNQmbwyjgg1UjHDh2UU8A==" }, - "dashdash": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.10.1.tgz", - "integrity": "sha512-hu/OyjwJnarCHKBL1eM4ZaRn00dwRwfSOR316vE5IO7PO4iM+xMx6xOY2g76yRwq+OHBrmb5oh74tVr27piJTQ==", - "requires": { - "assert-plus": "0.1.x" - }, - "dependencies": { - "assert-plus": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==" - } - } - }, - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -4987,12 +4793,6 @@ "verror": "1.10.0" } }, - "moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "optional": true - }, "restify-clients": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/restify-clients/-/restify-clients-1.6.0.tgz", @@ -5014,132 +4814,6 @@ "uuid": "^3.0.1" } }, - "smartdc-auth": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/smartdc-auth/-/smartdc-auth-2.5.7.tgz", - "integrity": "sha512-QOcZhborgBHdz3kLOC7aXjU/ELqXdl2lsljVDwzin6NhamIebfbwAmORynptDKqposniQ9yY5cqGgxUQvwlveA==", - "requires": { - "assert-plus": "^1.0.0", - "bunyan": "1.8.12", - "clone": "0.1.5", - "dashdash": "1.10.1", - "http-signature": "^1.0.2", - "once": "1.3.0", - "sshpk": "^1.8.3", - "sshpk-agent": "^1.3.0", - "vasync": "1.4.3" - }, - "dependencies": { - "bunyan": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", - "requires": { - "dtrace-provider": "~0.8", - "moment": "^2.10.6", - "mv": "~2", - "safe-json-stringify": "~1" - } - }, - "clone": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.1.5.tgz", - "integrity": "sha512-icqCXhZwHg0fpiRngRxgxhehGAnrnaIM5whGwpjyajCqx5bqonZW1SsRRWutDV/LXDMqbgEx6EC07vQG24pVbQ==" - }, - "extsprintf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.0.tgz", - "integrity": "sha512-AtBFy+ysvNodhorg/XoW8l+3VtfhILEWc53shEOsAuyDQTnQoXDfI2x9c93QY+RMdCQWAbL0XqpidgJe3BOCFA==" - }, - "json-schema": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", - "integrity": "sha512-DFzwwaFNKI+cfMyHtcyGA6N9d8jOWEtLc9IrT7WbpZc1V8M5S/HMBjJ3aM2Fx40bcTL2xTuIX/bBr8Zj2soGyg==" - }, - "jsprim": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.3.0.tgz", - "integrity": "sha512-lPLTWfTELEgTAY3mphlaIjYa5j6n1XFB3ju+nqFGNXTvX1ZXArW8fwEzq+i+ggILHaBRQkhzeMiQ+M56FbWU6A==", - "requires": { - "extsprintf": "1.0.0", - "json-schema": "0.2.2", - "verror": "1.3.3" - }, - "dependencies": { - "verror": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.3.tgz", - "integrity": "sha512-FRyhVjZX8Hy5Mlmvo4YbbN3V8KaagA6W6Xc3kNOtIQqd3DohGqQzqie1NDVfZbZuWZjCTF0E5PNUqQZ5BVqdew==", - "requires": { - "extsprintf": "1.0.0" - } - } - } - }, - "once": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.0.tgz", - "integrity": "sha512-A31oqbdEQnnhkjIXJ6QKcgO9eN8Xe+dVAQqlFLAmri0Y5s11pUadCihT2popU2WLd5CbbnD2ZVkbEJsR/8JHvA==" - }, - "vasync": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/vasync/-/vasync-1.4.3.tgz", - "integrity": "sha512-GHLh6i4OfvQgc3KeznwMtw45I+fTyYYCyD1fOngn9Q5wURmwKuX95C8VunSn267KAX8Pg200hkgZPgTwBwMLyQ==", - "requires": { - "jsprim": "0.3.0", - "verror": "1.1.0" - } - }, - "verror": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.1.0.tgz", - "integrity": "sha512-5X/HjC1yBdrpYrQvjUC55HB1CuRPyk1b+Fz0Rpp60fhQR9aE4hcjnRwFfPNF7SNwoCb5fMrjGHr7Gla0zUerXA==", - "requires": { - "extsprintf": "1.0.0" - } - } - } - }, - "sshpk-agent": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sshpk-agent/-/sshpk-agent-1.8.1.tgz", - "integrity": "sha512-YzAzemVrXEf1OeZUpveXLeYUT5VVw/I5gxLeyzq1aMS3pRvFvCeaGliNFjKR3VKtGXRqF9WamqKwYadIG6vStQ==", - "requires": { - "assert-plus": "^1.0.0", - "dashdash": "^1.14.1", - "getpass": "^0.1.7", - "mooremachine": "^2.0.1", - "readable-stream": "^2.1.4", - "sshpk": ">=1.14.1 < 1.17.0", - "verror": "^1.10.0" - }, - "dependencies": { - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - } - } - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -5260,29 +4934,15 @@ "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" - }, - "dependencies": { - "object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" - } } }, "side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "requires": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "dependencies": { - "object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" - } + "object-inspect": "^1.13.4" } }, "side-channel-map": { @@ -5294,13 +4954,6 @@ "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" - }, - "dependencies": { - "object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" - } } }, "side-channel-weakmap": { @@ -5313,13 +4966,6 @@ "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" - }, - "dependencies": { - "object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" - } } }, "signal-exit": { @@ -5364,27 +5010,12 @@ "vasync": "1.6.2" }, "dependencies": { - "asn1": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "integrity": "sha512-Fh9zh3G2mZ8qM/kwsiKwL2U2FmXxVsboP4x1mXjnhKHv3SmzaBZoYvxEQJz/YS2gnCgd8xlAVWcZnQyC9qZBsA==", - "dev": true - }, "assert-plus": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==", "dev": true }, - "backoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", - "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", - "dev": true, - "requires": { - "precond": "0.2" - } - }, "bunyan": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz", @@ -5402,18 +5033,31 @@ "integrity": "sha512-f1p5UdkIdJ3iXH0h8wY/DQ0ikbmMBdOI1Wo1NmWJ+FUOt1UEeFjOBHNtpRxncMTgjA+0nmjLdRrjA0ba9JkdIg==", "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, "ctype": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", "integrity": "sha512-T6CEkoSV4q50zW3TlTHMbzy1E5+zlnNcY+yb7tWVYlTwPhx9LpnfAkd4wecpWknDyptp4k97LUZeInlf6jdzBg==", "dev": true }, + "dashdash": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.7.3.tgz", + "integrity": "sha512-NxuWFXR3+HJULO6F6VprWnUQbx0MXgfEuOfz3m+pw8LYZV06SHRjcaBVvVlwH132xJq12mljySVDLcbMcFM7EA==", + "dev": true, + "requires": { + "assert-plus": "0.1.x" + } + }, + "dtrace-provider": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", + "integrity": "sha512-yqNrDWYWOR3wumcWPhlIGIKRSFMbDEwilGi+xYeaY4wW82cZrWsqGE+jsVnouxMqt/kCVsNmy/XDXLrm/J6SJg==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.0.8" + } + }, "extsprintf": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz", @@ -5437,20 +5081,23 @@ "integrity": "sha512-nnQiy1lsNj5xmeoe48piKcv2xWdL6KXxJeN3aobdSH939OMTK/qXRkuVSVAM59nS2KMPBeuqx5GD+e8JbZwPdQ==", "dev": true }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true + "negotiator": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz", + "integrity": "sha512-oXmnazqehLNFohqgLxRyUdOQU9/UX0NpCpsnbjWUjM62ZM8oSOXYZpHc68XR130ftPNano0oQXGdREAplZRhaQ==", + "dev": true }, - "nopt": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.0.0.tgz", - "integrity": "sha512-uVTsuT8Hm3aN3VttY+BPKw4KU9lVpI0F22UAr/I1r6+kugMr3oyhMALkycikLcdfvGRsgzCYN48DYLBFcJEUVg==", - "dev": true, - "requires": { - "abbrev": "1" - } + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==", + "dev": true + }, + "qs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-3.1.0.tgz", + "integrity": "sha512-nR5uYqNsm8CgBhfCpsYKz6iDhvKjf0xdFT4KanNlLP40COGwZEsjbLoDyL9VrTXyiICUGUbsiN3gBpLGZhSZWQ==", + "dev": true }, "restify": { "version": "4.0.3", @@ -5514,21 +5161,144 @@ "integrity": "sha512-IrpJ+yoG4EOH8DFWuVg+8H1kW1Oaof0Wxe7cPcXW3x9BjkN/eVo54F15LyqemnDIUYskQWr9qvl/RihmSy6+xQ==", "dev": true }, - "vasync": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/vasync/-/vasync-1.6.2.tgz", - "integrity": "sha512-wRXkN7O5REJ3vlYYb3DKD+yRrNdXG3LEsxUgZCJEz/uguoq26jzcqt+7cozBC8GSCAxj56YtHuualN5Rz+Hi3g==", + "smartdc-auth": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/smartdc-auth/-/smartdc-auth-2.3.1.tgz", + "integrity": "sha512-c3iQfVBeHIqsPW2vD7x3UcYuCl7QDNtQm+HLV3jB434hoi2A/jOOPqi1nLSuWQKX51v4j9+aMA0VN8LIOObTNw==", "dev": true, "requires": { - "verror": "1.1.0" + "assert-plus": "0.1.2", + "bunyan": "1.5.1", + "clone": "0.1.5", + "dashdash": "1.10.1", + "http-signature": ">=1.0.2 <2.0.0", + "once": "1.3.0", + "sshpk": "1.7.1", + "sshpk-agent": "1.2.1", + "vasync": "1.4.3" }, "dependencies": { + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz", + "integrity": "sha512-BbJV8Hq6grYTokkHi/qKS34kfYIFYpu4wKd/H0dARsa6qOqEFH1wboxMwrccAmFjyRjkemjElaVC/sZSUMxHnA==", + "dev": true + }, + "clone": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.1.5.tgz", + "integrity": "sha512-icqCXhZwHg0fpiRngRxgxhehGAnrnaIM5whGwpjyajCqx5bqonZW1SsRRWutDV/LXDMqbgEx6EC07vQG24pVbQ==", + "dev": true + }, + "dashdash": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.10.1.tgz", + "integrity": "sha512-hu/OyjwJnarCHKBL1eM4ZaRn00dwRwfSOR316vE5IO7PO4iM+xMx6xOY2g76yRwq+OHBrmb5oh74tVr27piJTQ==", + "dev": true, + "requires": { + "assert-plus": "0.1.x" + } + }, "extsprintf": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.0.tgz", "integrity": "sha512-AtBFy+ysvNodhorg/XoW8l+3VtfhILEWc53shEOsAuyDQTnQoXDfI2x9c93QY+RMdCQWAbL0XqpidgJe3BOCFA==", "dev": true }, + "http-signature": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", + "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.18.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + } + } + }, + "once": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.0.tgz", + "integrity": "sha512-A31oqbdEQnnhkjIXJ6QKcgO9eN8Xe+dVAQqlFLAmri0Y5s11pUadCihT2popU2WLd5CbbnD2ZVkbEJsR/8JHvA==", + "dev": true + }, + "vasync": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-1.4.3.tgz", + "integrity": "sha512-GHLh6i4OfvQgc3KeznwMtw45I+fTyYYCyD1fOngn9Q5wURmwKuX95C8VunSn267KAX8Pg200hkgZPgTwBwMLyQ==", + "dev": true, + "requires": { + "jsprim": "0.3.0", + "verror": "1.1.0" + }, + "dependencies": { + "jsprim": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.3.0.tgz", + "integrity": "sha512-lPLTWfTELEgTAY3mphlaIjYa5j6n1XFB3ju+nqFGNXTvX1ZXArW8fwEzq+i+ggILHaBRQkhzeMiQ+M56FbWU6A==", + "dev": true, + "requires": { + "extsprintf": "1.0.0", + "json-schema": "0.2.2", + "verror": "1.3.3" + }, + "dependencies": { + "verror": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.3.tgz", + "integrity": "sha512-FRyhVjZX8Hy5Mlmvo4YbbN3V8KaagA6W6Xc3kNOtIQqd3DohGqQzqie1NDVfZbZuWZjCTF0E5PNUqQZ5BVqdew==", + "dev": true, + "requires": { + "extsprintf": "1.0.0" + } + } + } + } + } + }, "verror": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.1.0.tgz", @@ -5540,66 +5310,123 @@ } } }, - "verror": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "spdy": { + "version": "1.32.5", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-1.32.5.tgz", + "integrity": "sha512-4bSLdgzl0xcMto0zPmhLRfy7y8ZWSjcv+znurjcUnzW5ZQhhDo+HKIRdAB+n/mTde+KEfoQKYzehc6pUHrRQYw==", + "dev": true + }, + "sshpk": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.7.1.tgz", + "integrity": "sha512-5tF1bCTJM3L2EPeg25Njg91c231xKXrTthIOwFzRJo5DSdnaoC8SVTZvX4NcXsbu16LoszUuOyj+RzBa9E4law==", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "asn1": ">=0.2.3 <0.3.0", + "assert-plus": ">=0.2.0 <0.3.0", + "dashdash": ">=1.10.1 <2.0.0", + "ecc-jsbn": ">=0.0.1 <1.0.0", + "jodid25519": ">=1.0.0 <2.0.0", + "jsbn": ">=0.1.0 <0.2.0", + "tweetnacl": ">=0.13.0 <1.0.0" }, "dependencies": { + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true + } + } + } + } + }, + "sshpk-agent": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sshpk-agent/-/sshpk-agent-1.2.1.tgz", + "integrity": "sha512-qszxcSCziI1IEv7SbVc51dqmyck1f520I92duwBWGRFtPQXz52ErYr6cAPEVWa4EkWNI4fMbPgagi2/oNpuuRg==", + "dev": true, + "requires": { + "assert-plus": ">=0.1.5 <0.2.0", + "readable-stream": ">=2.0.0 <3.0.0", + "sshpk": ">=1.7.0 <1.8" + } + }, + "vasync": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-1.6.2.tgz", + "integrity": "sha512-wRXkN7O5REJ3vlYYb3DKD+yRrNdXG3LEsxUgZCJEz/uguoq26jzcqt+7cozBC8GSCAxj56YtHuualN5Rz+Hi3g==", + "dev": true, + "requires": { + "verror": "1.1.0" + }, + "dependencies": { + "extsprintf": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.0.tgz", + "integrity": "sha512-AtBFy+ysvNodhorg/XoW8l+3VtfhILEWc53shEOsAuyDQTnQoXDfI2x9c93QY+RMdCQWAbL0XqpidgJe3BOCFA==", "dev": true + }, + "verror": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.1.0.tgz", + "integrity": "sha512-5X/HjC1yBdrpYrQvjUC55HB1CuRPyk1b+Fz0Rpp60fhQR9aE4hcjnRwFfPNF7SNwoCb5fMrjGHr7Gla0zUerXA==", + "dev": true, + "requires": { + "extsprintf": "1.0.0" + } } } } } }, "smartdc-auth": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/smartdc-auth/-/smartdc-auth-2.3.1.tgz", - "integrity": "sha512-c3iQfVBeHIqsPW2vD7x3UcYuCl7QDNtQm+HLV3jB434hoi2A/jOOPqi1nLSuWQKX51v4j9+aMA0VN8LIOObTNw==", - "dev": true, + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/smartdc-auth/-/smartdc-auth-2.5.7.tgz", + "integrity": "sha512-QOcZhborgBHdz3kLOC7aXjU/ELqXdl2lsljVDwzin6NhamIebfbwAmORynptDKqposniQ9yY5cqGgxUQvwlveA==", "requires": { - "assert-plus": "0.1.2", - "bunyan": "1.5.1", + "assert-plus": "^1.0.0", + "bunyan": "1.8.12", "clone": "0.1.5", "dashdash": "1.10.1", - "http-signature": ">=1.0.2 <2.0.0", + "http-signature": "^1.0.2", "once": "1.3.0", - "sshpk": "1.7.1", - "sshpk-agent": "1.2.1", + "sshpk": "^1.8.3", + "sshpk-agent": "^1.3.0", "vasync": "1.4.3" }, "dependencies": { - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz", - "integrity": "sha512-BbJV8Hq6grYTokkHi/qKS34kfYIFYpu4wKd/H0dARsa6qOqEFH1wboxMwrccAmFjyRjkemjElaVC/sZSUMxHnA==", - "dev": true - }, "bunyan": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz", - "integrity": "sha512-gbSG0cjSr48Ifz5f9OyGcKPGKJewbK6F+KSQ59/KzjOjQK6Kox88JWk94xyIAOTzNPgbS5MLCkOyLdtVWPV4Cg==", - "dev": true, + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", + "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", "requires": { - "dtrace-provider": "~0.6", + "dtrace-provider": "~0.8", + "moment": "^2.10.6", "mv": "~2", "safe-json-stringify": "~1" } @@ -5607,196 +5434,74 @@ "clone": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/clone/-/clone-0.1.5.tgz", - "integrity": "sha512-icqCXhZwHg0fpiRngRxgxhehGAnrnaIM5whGwpjyajCqx5bqonZW1SsRRWutDV/LXDMqbgEx6EC07vQG24pVbQ==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "integrity": "sha512-icqCXhZwHg0fpiRngRxgxhehGAnrnaIM5whGwpjyajCqx5bqonZW1SsRRWutDV/LXDMqbgEx6EC07vQG24pVbQ==" }, "dashdash": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.10.1.tgz", "integrity": "sha512-hu/OyjwJnarCHKBL1eM4ZaRn00dwRwfSOR316vE5IO7PO4iM+xMx6xOY2g76yRwq+OHBrmb5oh74tVr27piJTQ==", - "dev": true, "requires": { "assert-plus": "0.1.x" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true - }, - "http-signature": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", - "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.18.0" }, "dependencies": { "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==" } } }, + "extsprintf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.0.tgz", + "integrity": "sha512-AtBFy+ysvNodhorg/XoW8l+3VtfhILEWc53shEOsAuyDQTnQoXDfI2x9c93QY+RMdCQWAbL0XqpidgJe3BOCFA==" + }, "jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.3.0.tgz", + "integrity": "sha512-lPLTWfTELEgTAY3mphlaIjYa5j6n1XFB3ju+nqFGNXTvX1ZXArW8fwEzq+i+ggILHaBRQkhzeMiQ+M56FbWU6A==", "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" + "extsprintf": "1.0.0", + "json-schema": "0.2.2", + "verror": "1.3.3" }, "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true + "verror": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.3.tgz", + "integrity": "sha512-FRyhVjZX8Hy5Mlmvo4YbbN3V8KaagA6W6Xc3kNOtIQqd3DohGqQzqie1NDVfZbZuWZjCTF0E5PNUqQZ5BVqdew==", + "requires": { + "extsprintf": "1.0.0" + } } } }, + "moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "optional": true + }, "once": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/once/-/once-1.3.0.tgz", - "integrity": "sha512-A31oqbdEQnnhkjIXJ6QKcgO9eN8Xe+dVAQqlFLAmri0Y5s11pUadCihT2popU2WLd5CbbnD2ZVkbEJsR/8JHvA==", - "dev": true - }, - "sshpk": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.7.1.tgz", - "integrity": "sha512-5tF1bCTJM3L2EPeg25Njg91c231xKXrTthIOwFzRJo5DSdnaoC8SVTZvX4NcXsbu16LoszUuOyj+RzBa9E4law==", - "dev": true, - "requires": { - "asn1": ">=0.2.3 <0.3.0", - "assert-plus": ">=0.2.0 <0.3.0", - "dashdash": ">=1.10.1 <2.0.0", - "ecc-jsbn": ">=0.0.1 <1.0.0", - "jodid25519": ">=1.0.0 <2.0.0", - "jsbn": ">=0.1.0 <0.2.0", - "tweetnacl": ">=0.13.0 <1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw==", - "dev": true - } - } + "integrity": "sha512-A31oqbdEQnnhkjIXJ6QKcgO9eN8Xe+dVAQqlFLAmri0Y5s11pUadCihT2popU2WLd5CbbnD2ZVkbEJsR/8JHvA==" }, "vasync": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/vasync/-/vasync-1.4.3.tgz", "integrity": "sha512-GHLh6i4OfvQgc3KeznwMtw45I+fTyYYCyD1fOngn9Q5wURmwKuX95C8VunSn267KAX8Pg200hkgZPgTwBwMLyQ==", - "dev": true, "requires": { "jsprim": "0.3.0", "verror": "1.1.0" - }, - "dependencies": { - "extsprintf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.0.tgz", - "integrity": "sha512-AtBFy+ysvNodhorg/XoW8l+3VtfhILEWc53shEOsAuyDQTnQoXDfI2x9c93QY+RMdCQWAbL0XqpidgJe3BOCFA==", - "dev": true - }, - "json-schema": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.2.tgz", - "integrity": "sha512-DFzwwaFNKI+cfMyHtcyGA6N9d8jOWEtLc9IrT7WbpZc1V8M5S/HMBjJ3aM2Fx40bcTL2xTuIX/bBr8Zj2soGyg==", - "dev": true - }, - "jsprim": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-0.3.0.tgz", - "integrity": "sha512-lPLTWfTELEgTAY3mphlaIjYa5j6n1XFB3ju+nqFGNXTvX1ZXArW8fwEzq+i+ggILHaBRQkhzeMiQ+M56FbWU6A==", - "dev": true, - "requires": { - "extsprintf": "1.0.0", - "json-schema": "0.2.2", - "verror": "1.3.3" - }, - "dependencies": { - "verror": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.3.tgz", - "integrity": "sha512-FRyhVjZX8Hy5Mlmvo4YbbN3V8KaagA6W6Xc3kNOtIQqd3DohGqQzqie1NDVfZbZuWZjCTF0E5PNUqQZ5BVqdew==", - "dev": true, - "requires": { - "extsprintf": "1.0.0" - } - } - } - }, - "verror": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.1.0.tgz", - "integrity": "sha512-5X/HjC1yBdrpYrQvjUC55HB1CuRPyk1b+Fz0Rpp60fhQR9aE4hcjnRwFfPNF7SNwoCb5fMrjGHr7Gla0zUerXA==", - "dev": true, - "requires": { - "extsprintf": "1.0.0" - } - } } }, "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.1.0.tgz", + "integrity": "sha512-5X/HjC1yBdrpYrQvjUC55HB1CuRPyk1b+Fz0Rpp60fhQR9aE4hcjnRwFfPNF7SNwoCb5fMrjGHr7Gla0zUerXA==", "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - } + "extsprintf": "1.0.0" } } } @@ -5819,6 +5524,31 @@ "rimraf": "^2.6.2", "signal-exit": "^3.0.2", "which": "^1.3.0" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "spdx-correct": { @@ -5848,16 +5578,23 @@ } }, "spdx-license-ids": { - "version": "3.0.22", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", - "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", "dev": true }, "spdy": { - "version": "1.32.5", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-1.32.5.tgz", - "integrity": "sha512-4bSLdgzl0xcMto0zPmhLRfy7y8ZWSjcv+znurjcUnzW5ZQhhDo+HKIRdAB+n/mTde+KEfoQKYzehc6pUHrRQYw==", - "dev": true + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", + "integrity": "sha512-jEvgkLRpMza5GON0oDzvLTLMAVfB5BxeOPbsWyisEyE8IbxL6cCiKbr8xrJdScs6XoOUp7pQy4PI+GVczHbO4w==", + "requires": { + "debug": "^2.6.8", + "handle-thing": "^1.2.5", + "http-deceiver": "^1.2.7", + "safe-buffer": "^5.0.1", + "select-hose": "^2.0.0", + "spdy-transport": "^2.0.18" + } }, "spdy-transport": { "version": "2.1.1", @@ -5871,21 +5608,6 @@ "readable-stream": "^2.2.9", "safe-buffer": "^5.0.1", "wbuf": "^1.7.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } } }, "sprintf-js": { @@ -5916,86 +5638,45 @@ "requires": { "safer-buffer": "~2.1.0" } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "requires": { - "assert-plus": "^1.0.0" - } } } }, "sshpk-agent": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sshpk-agent/-/sshpk-agent-1.2.1.tgz", - "integrity": "sha512-qszxcSCziI1IEv7SbVc51dqmyck1f520I92duwBWGRFtPQXz52ErYr6cAPEVWa4EkWNI4fMbPgagi2/oNpuuRg==", - "dev": true, + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sshpk-agent/-/sshpk-agent-1.8.1.tgz", + "integrity": "sha512-YzAzemVrXEf1OeZUpveXLeYUT5VVw/I5gxLeyzq1aMS3pRvFvCeaGliNFjKR3VKtGXRqF9WamqKwYadIG6vStQ==", "requires": { - "assert-plus": ">=0.1.5 <0.2.0", - "readable-stream": ">=2.0.0 <3.0.0", - "sshpk": ">=1.7.0 <1.8" + "assert-plus": "^1.0.0", + "dashdash": "^1.14.1", + "getpass": "^0.1.7", + "mooremachine": "^2.0.1", + "readable-stream": "^2.1.4", + "sshpk": ">=1.14.1 < 1.17.0", + "verror": "^1.10.0" }, "dependencies": { "asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } }, - "assert-plus": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - } - } - }, "sshpk": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.7.4.tgz", - "integrity": "sha512-p7+I1qlhKmgTIGmXu9DkQzjVig5uURH0xNWg/YU6O4YWsfCYoctnwbyrdgMcvzRmTBERMzOxVJifeaHlJLeLig==", - "dev": true, + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "requires": { - "asn1": ">=0.2.3 <0.3.0", - "assert-plus": ">=0.2.0 <0.3.0", - "dashdash": ">=1.10.1 <2.0.0", - "ecc-jsbn": ">=0.0.1 <1.0.0", - "jodid25519": ">=1.0.0 <2.0.0", - "jsbn": ">=0.1.0 <0.2.0", - "tweetnacl": ">=0.13.0 <1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw==", - "dev": true - } + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" } } } @@ -6069,6 +5750,13 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } } }, "strip-ansi": { @@ -6168,6 +5856,12 @@ "path-is-absolute": "^1.0.0" } }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, "resolve": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", @@ -6189,6 +5883,22 @@ "minimatch": "^3.0.4", "read-pkg-up": "^4.0.0", "require-main-filename": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "text-table": { @@ -6237,15 +5947,6 @@ "safe-json-stringify": "~1" } }, - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, "moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -6341,9 +6042,8 @@ "dev": true }, "ufds": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ufds/-/ufds-1.9.1.tgz", - "integrity": "sha512-SB+tvFriMybagZvY1owhXskilfLX4Csqv4/T1Y2yNjYN4JxkXbdtzVQPiTqMV7xtmJXEH5sIAkB3XOu2FyW5wQ==", + "version": "git+https://github.com/TritonDataCenter/node-ufds.git#f8ea6ad62fdf14b79ff95a784bdcca3d7723150a", + "from": "git+https://github.com/TritonDataCenter/node-ufds.git#f8ea6ad", "requires": { "assert-plus": "^0.2.0", "async": "~0.9.0", @@ -6379,30 +6079,6 @@ "resolved": "https://registry.npmjs.org/crc/-/crc-0.2.0.tgz", "integrity": "sha512-LFlOXOW6KT46bjpUevoixE6UQVdm9wMwCrR4JHxg4LJ+9COF7efwTdVMRXrSlNXYmUQgtAcHsWa0VgKBiQZmMQ==" }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "requires": { - "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - } - } - }, - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, "extsprintf": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.2.0.tgz", @@ -6516,9 +6192,9 @@ } }, "underscore": { - "version": "1.13.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", - "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==" + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==" }, "util-deprecate": { "version": "1.0.2", @@ -6563,10 +6239,10 @@ "extsprintf": "^1.2.0" }, "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" } } }, @@ -6600,14 +6276,6 @@ "readable-stream": "1.0.2" }, "dependencies": { - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "requires": { - "nan": "^2.14.0" - } - }, "readable-stream": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.2.tgz", @@ -6705,9 +6373,9 @@ "dev": true }, "which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", "dev": true, "requires": { "available-typed-arrays": "^1.0.7", From 4ebd180e126024892b33f0ea0d9add38270ae5a5 Mon Sep 17 00:00:00 2001 From: neirac Date: Mon, 27 Apr 2026 15:38:47 -0400 Subject: [PATCH 15/25] accesskeys: fix four review findings in scope endpoints 1. Create cachePush used hardcoded status 'Active' instead of the caller-provided status, causing Redis/UFDS disagreement when creating keys with status 'Inactive'. 2. Delete sent 204 before scopeRevoke completed, creating a security window where a deleted key remained usable in Redis. Now waits for scopeRevoke callback before responding. 3. Update cachePush did not guard against rawSecret being undefined (UFDS may strip sensitive attrs on update). Now skips cache-push and logs a warning if secret is missing. 4. Create scope check used truthiness (swallows 0/false/'') instead of !== undefined/null, inconsistent with update. AI-generated code. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/endpoints/accesskeys.js | 58 ++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 8d3789aa..3120e9ca 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -157,7 +157,8 @@ function create(req, res, next) { * * Absent/null scope means unrestricted. */ - if (req.params.scope) { + if (req.params.scope !== undefined && + req.params.scope !== null) { var result = validateScope(req.params.scope); if (!result.valid) { next(new InvalidArgumentError(result.error)); @@ -229,7 +230,8 @@ function create(req, res, next) { accesskeyid: accesskey.accesskeyid, accesskeysecret: accesskeysecret, ownerUuid: req.account.uuid, - status: 'Active', + status: params.status || + accesskey.status || 'Active', scope: params.accesskeyscope || null }, function (pushErr) { if (pushErr) { @@ -405,11 +407,13 @@ function del(req, res, next) { } /* - * Fire-and-forget: revoke key from mahi Redis - * immediately. Applies to all keys (not just - * scoped) because we don't have scope info at - * delete time without an extra UFDS read. - * Harmless no-op for unscoped keys. + * Revoke key from mahi Redis before responding. + * Deletion is security-sensitive: the key must + * not remain usable in the cache after the + * client receives 204. Applies to all keys + * (not just scoped) because we don't have + * scope info at delete time without an extra + * UFDS read. Harmless no-op for unscoped keys. */ if (req.sdc.mahi) { req.sdc.mahi.scopeRevoke( @@ -422,12 +426,18 @@ function del(req, res, next) { }, 'cache-revoke best-effort' + ' failed'); } + log.debug('DELETE %s -> ok', + req.path()); + res.send(204); + next(); + return; }); + } else { + log.debug('DELETE %s -> ok', req.path()); + res.send(204); + next(); + return; } - - log.debug('DELETE %s -> ok', req.path()); - res.send(204); - next(); }); } catch (e) { log.error({err: e}, 'delete accesskey exception'); @@ -504,11 +514,17 @@ function update(req, res, next) { } /* - * Capture secret before translateAccessKey strips - * it. Fire cache-push when scope changes OR when - * status changes on a key that has a scope (so - * deactivation of a scoped key propagates to - * Redis immediately). + * Capture secret before translateAccessKey + * strips it. Fire cache-push when scope + * changes OR when status changes on a key + * that has a scope (so deactivation of a + * scoped key propagates to Redis immediately). + * + * Guard: if UFDS did not return the secret + * (some LDAP stores strip sensitive attrs on + * update), skip the cache-push to avoid + * storing a broken entry. The replicator + * will catch up. */ var rawSecret = accesskey.accesskeysecret; var hasScope = params.accesskeyscope !== undefined || @@ -518,7 +534,15 @@ function update(req, res, next) { var statusChanged = params.status !== undefined; - if (req.sdc.mahi && hasScope && + if (!rawSecret && hasScope && + (scopeChanged || statusChanged)) { + log.warn({ + accesskeyid: params.accesskeyid + }, 'cache-push skipped: UFDS did not' + + ' return accesskeysecret on update'); + } + + if (req.sdc.mahi && rawSecret && hasScope && (scopeChanged || statusChanged)) { req.sdc.mahi.cachePush({ accesskeyid: params.accesskeyid, From 6f3e2a37f6b1fa8e52a00233d7bdc18aaf4ff4bd Mon Sep 17 00:00:00 2001 From: neirac Date: Mon, 4 May 2026 16:58:16 -0400 Subject: [PATCH 16/25] Add bucket-scope parameter to documentation --- docs/index.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/index.md b/docs/index.md index 72f00844..def62043 100644 --- a/docs/index.md +++ b/docs/index.md @@ -887,6 +887,10 @@ Note that a `Triton-Datacenter-Name` response header was added in 9.2.0. The section describes API changes in CloudAPI versions. +## 9.21.1 + +- Add an optional bucket-scope parameter when creating an accesskey. + ## 9.21.0 - Add ability to update an AccessKey's `status` and `description` field. @@ -3362,6 +3366,35 @@ Generates a new access key id and secret. ----------- | -------- | ------------------------------------------------------------------ status | String | `Active`, `Inactive`, or `Expired` (optional, default is `Active`) description | String | Description of Access Key (optional) +scope | Object. | Object describing permissions and bucket to which the accesskey will have access. + +The json schema of this optional parameter is the following: +```json + { + "type": "object", + "required": ["version", "permissions"], + "properties": { + "version": { "const": 1 }, + "permissions": { + "type": "array", + "minItems": 1, + "maxItems": 1000, + "items": { + "type": "object", + "required": ["bucket", "level"], + "properties": { + "bucket": { + "type": "string", + "maxLength": 63, + "pattern": "^(\\*|[a-z0-9][a-z0-9.\\-]*\\*?)$" + }, + "level": { "enum": ["read", "readwrite", "full"] } + } + } + } + } + } +``` ### Returns From 41a3169c36ca77743bd7ab8cb083064dee5e2f0a Mon Sep 17 00:00:00 2001 From: neirac Date: Mon, 4 May 2026 17:01:27 -0400 Subject: [PATCH 17/25] Fix inaccurate comment --- lib/endpoints/accesskeys.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 3120e9ca..56590353 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -473,9 +473,8 @@ function update(req, res, next) { } /* - * Update bucket scope. An empty string removes the - * scope (makes the key unrestricted again). A non- - * empty value replaces the scope. + * Update bucket scope. An empty string or null removes the scope (makes + * the key unrestricted again). A non-empty value replaces the scope. */ if (req.params.scope !== undefined) { if (req.params.scope === '' || From 8498be3e9408f5ff2013646cd467ca33b64ecfa5 Mon Sep 17 00:00:00 2001 From: neirac Date: Mon, 4 May 2026 17:11:00 -0400 Subject: [PATCH 18/25] Update copyright --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index def62043..ba328db1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,7 +15,7 @@ markdown2extras: tables, code-friendly Copyright 2021 Joyent, Inc. Copyright 2021 The University of Queensland Copyright 2024 MNX Cloud, Inc. - Copyright 2025 Edgecast Cloud LLC. + Copyright 2026 Edgecast Cloud LLC. --> From 3ebbd85a0895e50e1fdcef0ee1df0ad0b5bc9ebf Mon Sep 17 00:00:00 2001 From: neirac Date: Wed, 6 May 2026 15:20:24 -0400 Subject: [PATCH 19/25] Fix horizontal white space --- lib/endpoints/accesskeys.js | 77 +++++++++++++++---------------------- 1 file changed, 31 insertions(+), 46 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 56590353..de256ac1 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -35,9 +35,8 @@ var MAX_KEYS = 100; /** * @brief Validate a scope parameter from the request * - * Delegates to the canonical scope schema module in - * node-mahi. Accepts only the canonical envelope: - * {"version":1,"permissions":[{bucket,level},...]} + * Delegates to the canonical scope schema module in node-mahi. Accepts only the + * canonical envelope: {"version":1,"permissions":[{bucket,level},...]} * * @param {Object} input - Scope envelope object * @return {Object} {valid: bool, scope: string|null, @@ -51,9 +50,8 @@ function validateScope(input) { /** * @brief Translate UFDS access key to API response format * - * Maps internal UFDS attributes to the external API - * representation. Includes the accesskeyscope field - * as a parsed JSON object when present. + * Maps internal UFDS attributes to the external API representation. Includes + * the accesskeyscope field as a parsed JSON object when present. * * @param {Object} accesskey - UFDS access key entry * @return {Object} Translated access key for response @@ -93,14 +91,12 @@ function translateAccessKey(accesskey) { } /* - * Return bucket scope as a parsed JSON object so - * callers can inspect permissions directly. When - * absent the key is unrestricted. + * Return bucket scope as a parsed JSON object so callers can inspect + * permissions directly. When absent the key is unrestricted. */ if (accesskey.accesskeyscope) { try { - translated.scope = - JSON.parse(accesskey.accesskeyscope); + translated.scope = JSON.parse(accesskey.accesskeyscope); } catch (_e) { translated.scope = null; } @@ -151,9 +147,8 @@ function create(req, res, next) { } /* - * Per-bucket access key scoping. Scope must be the - * canonical envelope: - * {"version":1,"permissions":[{bucket,level},...]} + * Per-bucket access key scoping. Scope must be the canonical envelope: + * {"version":1,"permissions":[{bucket,level},...]} * * Absent/null scope means unrestricted. */ @@ -216,14 +211,13 @@ function create(req, res, next) { var accesskeysecret = accesskey.accesskeysecret; /* - * Fire-and-forget: push key to mahi Redis - * for immediate availability (bypasses - * replicator delay). Best-effort — replicator - * is the authoritative fallback. + * Fire-and-forget: push key to mahi Redis for immediate + * availability (bypasses replicator delay). Best-effort — + * replicator is the authoritative fallback. * - * Push ALL keys (not just scoped) so that - * newly created keys are usable immediately - * without waiting for UFDS→Redis replication. + * Push ALL keys (not just scoped) so that newly created + * keys are usable immediately without waiting for + * UFDS→Redis replication. */ if (req.sdc.mahi) { req.sdc.mahi.cachePush({ @@ -407,13 +401,11 @@ function del(req, res, next) { } /* - * Revoke key from mahi Redis before responding. - * Deletion is security-sensitive: the key must - * not remain usable in the cache after the - * client receives 204. Applies to all keys - * (not just scoped) because we don't have - * scope info at delete time without an extra - * UFDS read. Harmless no-op for unscoped keys. + * Revoke key from mahi Redis before responding. Deletion is + * security-sensitive: the key must not remain usable in the cache + * after the client receives 204. Applies to all keys (not just + * scoped) because we don't have scope info at delete time without + * an extra UFDS read. Harmless no-op for unscoped keys. */ if (req.sdc.mahi) { req.sdc.mahi.scopeRevoke( @@ -513,17 +505,14 @@ function update(req, res, next) { } /* - * Capture secret before translateAccessKey - * strips it. Fire cache-push when scope - * changes OR when status changes on a key - * that has a scope (so deactivation of a - * scoped key propagates to Redis immediately). + * Capture secret before translateAccessKey strips it. Fire + * cache-push when scope changes OR when status changes on a key + * that has a scope (so deactivation of a scoped key propagates to + * Redis immediately). * - * Guard: if UFDS did not return the secret - * (some LDAP stores strip sensitive attrs on - * update), skip the cache-push to avoid - * storing a broken entry. The replicator - * will catch up. + * Guard: if UFDS did not return the secret (some LDAP stores strip + * sensitive attrs on update), skip the cache-push to avoid storing + * a broken entry. The replicator will catch up. */ var rawSecret = accesskey.accesskeysecret; var hasScope = params.accesskeyscope !== undefined || @@ -538,7 +527,7 @@ function update(req, res, next) { log.warn({ accesskeyid: params.accesskeyid }, 'cache-push skipped: UFDS did not' + - ' return accesskeysecret on update'); + ' return accesskeysecret on update'); } if (req.sdc.mahi && rawSecret && hasScope && @@ -556,8 +545,7 @@ function update(req, res, next) { if (pushErr) { log.warn({err: pushErr, accesskeyid: params.accesskeyid - }, 'cache-push best-effort' + - ' failed'); + }, 'cache-push best-effort' + ' failed'); } }); } @@ -566,14 +554,11 @@ function update(req, res, next) { if (account) { res.header('Location', - sprintf('/%s/users/%s/accesskeys/%s', - login, - user, + sprintf('/%s/users/%s/accesskeys/%s', login, user, encodeURIComponent(accesskey.accesskeyid))); } else { res.header('Location', - sprintf('/%s/accesskeys/%s', - login, + sprintf('/%s/accesskeys/%s', login, encodeURIComponent(accesskey.accesskeyid))); } From 965c47818a2bc850ee53b3878d74873a7967b0a2 Mon Sep 17 00:00:00 2001 From: neirac Date: Thu, 7 May 2026 10:48:45 -0400 Subject: [PATCH 20/25] fix horizontal white space --- lib/endpoints/accesskeys.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index de256ac1..695bf6b3 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -232,8 +232,7 @@ function create(req, res, next) { log.warn({err: pushErr, accesskeyid: accesskey.accesskeyid - }, 'cache-push best-effort' + - ' failed'); + }, 'cache-push best-effort failed'); } }); } @@ -415,8 +414,7 @@ function del(req, res, next) { log.warn({err: revokeErr, accesskeyid: req.params.accesskeyid - }, 'cache-revoke best-effort' + - ' failed'); + }, 'cache-revoke best-effort failed'); } log.debug('DELETE %s -> ok', req.path()); From 1867efb22f127e0101f765a17d7ff3d65b5e9fbd Mon Sep 17 00:00:00 2001 From: neirac Date: Tue, 12 May 2026 15:02:19 -0400 Subject: [PATCH 21/25] drop the misleading per-instance cache mutation from accesskeys cloudapi was calling mahi cachePush on create / update and scopeRevoke on delete as a per-instance Redis warm-up. Those calls only ever reached the single mahi instance cloudapi could resolve by name (the SDC mahi pool), never the Manta authcache pool that serves the S3 data plane. They were an SDC-side micro-optimisation that the existing sigv4 read-through (which falls through to UFDS on Redis miss) already makes irrelevant. For the Manta data plane, each authcache instance runs its own mahi-replicator that polls UFDS independently and applies key create / update / delete to local Redis on its own schedule. The replicator is and always was the consistency mechanism for those caches. cloudapi has no useful work to do there. After this change, create() / update() / del() in lib/endpoints/accesskeys.js write UFDS and respond. They do not contact mahi. The comment blocks are rewritten to describe the model accurately: UFDS is authoritative, the replicator applies changes to every Redis on its own schedule, the sigv4 read-through resolves cache misses against UFDS directly. Behaviour observable to callers: - CREATE then immediate use of the new key: ~0s, as today. - UPDATE: cache freshness on the Manta authcache pool bounded by the replicator interval (unchanged from previous reality; the prior cachePush did not affect that pool). - DELETE: deleted key remains valid on each authcache until its replicator picks up the UFDS deletion (unchanged for the same reason). No new failure modes. The file no longer references req.sdc.mahi. === AI-METADATA === AI-Tool: Claude Code AI-Model: claude-opus-4-7 AI-Role: refactor / cleanup AI-Confidence: high Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/endpoints/accesskeys.js | 141 ++++++++++-------------------------- 1 file changed, 40 insertions(+), 101 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 695bf6b3..4faee544 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -211,31 +211,14 @@ function create(req, res, next) { var accesskeysecret = accesskey.accesskeysecret; /* - * Fire-and-forget: push key to mahi Redis for immediate - * availability (bypasses replicator delay). Best-effort — - * replicator is the authoritative fallback. - * - * Push ALL keys (not just scoped) so that newly created - * keys are usable immediately without waiting for - * UFDS→Redis replication. + * UFDS is authoritative. On a Redis miss, the + * mahi sigv4 read-through resolves the new key + * directly from UFDS on every authcache + * instance — that is what makes the new key + * usable on the first signed request without + * waiting for the replicator. We do not write + * to mahi from here. */ - if (req.sdc.mahi) { - req.sdc.mahi.cachePush({ - accesskeyid: accesskey.accesskeyid, - accesskeysecret: accesskeysecret, - ownerUuid: req.account.uuid, - status: params.status || - accesskey.status || 'Active', - scope: params.accesskeyscope || null - }, function (pushErr) { - if (pushErr) { - log.warn({err: pushErr, - accesskeyid: - accesskey.accesskeyid - }, 'cache-push best-effort failed'); - } - }); - } accesskey = translateAccessKey(accesskey); @@ -400,34 +383,23 @@ function del(req, res, next) { } /* - * Revoke key from mahi Redis before responding. Deletion is - * security-sensitive: the key must not remain usable in the cache - * after the client receives 204. Applies to all keys (not just - * scoped) because we don't have scope info at delete time without - * an extra UFDS read. Harmless no-op for unscoped keys. + * UFDS is authoritative. Each authcache instance has + * its own mahi-replicator that polls UFDS and applies + * the deletion to local Redis on its own schedule. On + * a Redis miss the sigv4 read-through resolves the + * current state from UFDS directly. We do not call + * mahi from here: per-instance cache mutation from + * cloudapi was a misleading optimisation — it only + * ever reached the single mahi instance cloudapi + * could resolve by name, never the Manta authcache + * pool that serves the S3 data plane. The replicator + * is the consistency mechanism for every Redis + * holding this key. */ - if (req.sdc.mahi) { - req.sdc.mahi.scopeRevoke( - req.params.accesskeyid, - function (revokeErr) { - if (revokeErr) { - log.warn({err: revokeErr, - accesskeyid: - req.params.accesskeyid - }, 'cache-revoke best-effort failed'); - } - log.debug('DELETE %s -> ok', - req.path()); - res.send(204); - next(); - return; - }); - } else { - log.debug('DELETE %s -> ok', req.path()); - res.send(204); - next(); - return; - } + log.debug('DELETE %s -> ok', req.path()); + res.send(204); + next(); + return; }); } catch (e) { log.error({err: e}, 'delete accesskey exception'); @@ -503,69 +475,36 @@ function update(req, res, next) { } /* - * Capture secret before translateAccessKey strips it. Fire - * cache-push when scope changes OR when status changes on a key - * that has a scope (so deactivation of a scoped key propagates to - * Redis immediately). - * - * Guard: if UFDS did not return the secret (some LDAP stores strip - * sensitive attrs on update), skip the cache-push to avoid storing - * a broken entry. The replicator will catch up. + * UFDS is authoritative. Each authcache instance has + * its own mahi-replicator that polls UFDS and + * applies the update to local Redis on its own + * schedule. We do not call mahi from here — see the + * matching comment in del() above. */ - var rawSecret = accesskey.accesskeysecret; - var hasScope = params.accesskeyscope !== undefined || - accesskey.accesskeyscope; - var scopeChanged = - params.accesskeyscope !== undefined; - var statusChanged = - params.status !== undefined; - - if (!rawSecret && hasScope && - (scopeChanged || statusChanged)) { - log.warn({ - accesskeyid: params.accesskeyid - }, 'cache-push skipped: UFDS did not' + - ' return accesskeysecret on update'); - } - - if (req.sdc.mahi && rawSecret && hasScope && - (scopeChanged || statusChanged)) { - req.sdc.mahi.cachePush({ - accesskeyid: params.accesskeyid, - accesskeysecret: rawSecret, - ownerUuid: req.account.uuid, - status: params.status || - accesskey.status || 'Active', - scope: scopeChanged - ? params.accesskeyscope - : (accesskey.accesskeyscope || null) - }, function (pushErr) { - if (pushErr) { - log.warn({err: pushErr, - accesskeyid: params.accesskeyid - }, 'cache-push best-effort' + ' failed'); - } - }); - } - accesskey = translateAccessKey(accesskey); if (account) { res.header('Location', - sprintf('/%s/users/%s/accesskeys/%s', login, user, - encodeURIComponent(accesskey.accesskeyid))); + sprintf('/%s/users/%s/accesskeys/%s', login, + user, + encodeURIComponent( + accesskey.accesskeyid))); } else { res.header('Location', sprintf('/%s/accesskeys/%s', login, - encodeURIComponent(accesskey.accesskeyid))); + encodeURIComponent( + accesskey.accesskeyid))); } if (req.headers['role-tag'] || req.activeRoles) { - // The resource we want to save is the individual one we've - // just created, not the collection URI: + /* + * The resource we want to save is the + * individual one we've just updated, not the + * collection URI. + */ req.resourcename = req.resourcename + '/' + accesskey.accesskeyid; - req.resource = { + req.resource = { name: req.resourcename, account: req.account.uuid, roles: [] From f0f68bbad7710a8578b597795919e862606851b8 Mon Sep 17 00:00:00 2001 From: neirac Date: Tue, 12 May 2026 18:50:47 -0400 Subject: [PATCH 22/25] update node-mahi --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 94e97735..5742924e 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "kang": "^1.3.0", "keyapi": "git+https://github.com/TritonDataCenter/keyapi.git#bedd6fe787a4f3f3942724b37baed19162c8f074", "krill": "1.0.1", - "mahi": "git+https://github.com/TritonDataCenter/node-mahi.git#62c2486", + "mahi": "git+https://github.com/TritonDataCenter/node-mahi.git#012b503", "mime": "^1.6.0", "mooremachine": "^2.3.0", "nodemailer": "0.7.1", From c4b61e7ba063d822bf41f431df983162a05142f3 Mon Sep 17 00:00:00 2001 From: neirac Date: Tue, 12 May 2026 18:52:07 -0400 Subject: [PATCH 23/25] bump minor version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5742924e..01f94d24 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cloudapi", "description": "Triton CloudAPI", - "version": "9.21.1", + "version": "9.22.0", "author": "Edgecast Cloud (edgecast.io)", "private": true, "engines": { From 1a3155340087080ae712d81cf4dac52f7b900e7a Mon Sep 17 00:00:00 2001 From: neirac Date: Wed, 13 May 2026 18:18:55 -0400 Subject: [PATCH 24/25] Fix indentation --- lib/endpoints/accesskeys.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/endpoints/accesskeys.js b/lib/endpoints/accesskeys.js index 4faee544..47a1e188 100644 --- a/lib/endpoints/accesskeys.js +++ b/lib/endpoints/accesskeys.js @@ -62,8 +62,8 @@ function translateAccessKey(accesskey) { } var translated = { - accesskeyid: accesskey.accesskeyid, - credentialtype: accesskey.credentialtype || 'permanent' + accesskeyid: accesskey.accesskeyid, + credentialtype: accesskey.credentialtype || 'permanent' }; if (accesskey.status) { @@ -243,7 +243,7 @@ function create(req, res, next) { // we've just created, not the collection URI: req.resourcename = req.resourcename + '/' + accesskey.accesskeyid; - req.resource = { + req.resource = { name: req.resourcename, account: req.account.uuid, roles: [] From 8177ee67d0e5c560f9f2c9c0c6680404b129ecae Mon Sep 17 00:00:00 2001 From: neirac Date: Fri, 15 May 2026 15:04:40 -0400 Subject: [PATCH 25/25] Fix version to match package.json, clarify null scope option. --- docs/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index ba328db1..ecd31b5a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -887,9 +887,10 @@ Note that a `Triton-Datacenter-Name` response header was added in 9.2.0. The section describes API changes in CloudAPI versions. -## 9.21.1 +## 9.22.0 - Add an optional bucket-scope parameter when creating an accesskey. +- `UpdateAccessKey` now returns 200 status code on success instead of 201. ## 9.21.0 @@ -3366,7 +3367,7 @@ Generates a new access key id and secret. ----------- | -------- | ------------------------------------------------------------------ status | String | `Active`, `Inactive`, or `Expired` (optional, default is `Active`) description | String | Description of Access Key (optional) -scope | Object. | Object describing permissions and bucket to which the accesskey will have access. +scope | Object. | Object describing permissions and bucket to which the accesskey will have access. _If_ `null` then the scope is unrestricted. The json schema of this optional parameter is the following: ```json