@serviceme/devtools-shared 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1098,11 +1098,11 @@ export interface CopilotCustomizationViewPayload {
1098
1098
  * server (verifier).
1099
1099
  *
1100
1100
  * Single source of truth for the `x-ms-device-*` header names and the
1101
- * HMAC-SHA-256 request-signature algorithm. Previously the same
1102
- * constants + function were copy-pasted in three places
1103
- * (extension `services/device/deviceAuth.ts`, core `device/deviceAuth.ts`,
1104
- * server `lib/auth/device-signature-guard.ts`) and kept in sync by
1105
- * comments alone. Server and extension now import from here.
1101
+ * request-signature algorithms. Previously the same constants +
1102
+ * functions were copy-pasted in three places (extension
1103
+ * `services/device/deviceAuth.ts`, core `device/deviceAuth.ts`, server
1104
+ * `lib/auth/device-signature-guard.ts`) and kept in sync by comments
1105
+ * alone. Server and extension now import from here.
1106
1106
  *
1107
1107
  * NOTE: `packages/serviceme-core/src/device/deviceAuth.ts` keeps its own
1108
1108
  * copy — ADL-003 forbids core → shared (and shared → core) so the core
@@ -1117,7 +1117,15 @@ export declare const DeviceAuthHeaders: {
1117
1117
  readonly signature: "x-ms-device-signature";
1118
1118
  readonly timestamp: "x-ms-device-timestamp";
1119
1119
  readonly secretVersion: "x-ms-device-secret-version";
1120
+ /** v2 only — algorithm self-declaration so the server can verify
1121
+ * both schemes during the legacy-client rollout window. */
1122
+ readonly sigAlg: "x-ms-device-sig-alg";
1123
+ /** v2 only — one-time value folded into the signature basis and
1124
+ * checked against a server-side replay cache. */
1125
+ readonly nonce: "x-ms-device-nonce";
1120
1126
  };
1127
+ /** v2 signature algorithm identifier carried in `x-ms-device-sig-alg`. */
1128
+ export declare const DEVICE_SIG_ALG_V2 = "hmac-sha256-v2";
1121
1129
  export interface DeviceRequestSignatureParams {
1122
1130
  method: string;
1123
1131
  path: string;
@@ -1126,8 +1134,12 @@ export interface DeviceRequestSignatureParams {
1126
1134
  secret: string;
1127
1135
  }
1128
1136
  /**
1129
- * Basis is `METHOD\nPATH\nTIMESTAMP\nBODY\nSECRET` (LF-joined, NOT JSON).
1130
- * Output is lowercase hex SHA-256.
1137
+ * Legacy (v1) basis: `METHOD\nPATH\nTIMESTAMP\nBODY\nSECRET`
1138
+ * (LF-joined, NOT JSON), hashed with a secret-suffix SHA-256.
1139
+ * Output is lowercase hex.
1140
+ *
1141
+ * Retained for backward compatibility with fielded extensions that
1142
+ * predate v2; new code should use `createDeviceRequestSignatureV2`.
1131
1143
  *
1132
1144
  * Uses `js-sha256` (pure JS, synchronous, browser + Node) instead of
1133
1145
  * `node:crypto` so this module stays importable from the webview (the
@@ -1135,6 +1147,30 @@ export interface DeviceRequestSignatureParams {
1135
1147
  * the vite/rollup build).
1136
1148
  */
1137
1149
  export declare function createDeviceRequestSignature(params: DeviceRequestSignatureParams): string;
1150
+ export interface DeviceRequestSignatureV2Params {
1151
+ method: string;
1152
+ /** Full request path INCLUDING the query string (e.g.
1153
+ * `/api/v1/tools/rtk/download?version=1.2.0&target=darwin-arm64`).
1154
+ * v2 signs the query so GET parameters cannot be substituted or
1155
+ * replayed independently of the signed basis. */
1156
+ path: string;
1157
+ timestamp: number;
1158
+ /** One-time value; the server tracks seen nonces per device and
1159
+ * rejects replays within the timestamp window. */
1160
+ nonce: string;
1161
+ body: string;
1162
+ secret: string;
1163
+ }
1164
+ /**
1165
+ * v2 basis: `METHOD\nPATH?QUERY\nTIMESTAMP\nNONCE\nBODY\nSECRET`
1166
+ * (LF-joined, NOT JSON), MACed with real HMAC-SHA-256 keyed by the
1167
+ * device secret. Output is lowercase hex.
1168
+ *
1169
+ * The client MUST build the exact query string it will send before
1170
+ * signing — the server verifies against the raw `request.url` search,
1171
+ * so the signed string and the wire URL have to match byte-for-byte.
1172
+ */
1173
+ export declare function createDeviceRequestSignatureV2(params: DeviceRequestSignatureV2Params): string;
1138
1174
  //#endregion
1139
1175
  //#region src/git-utils.d.ts
1140
1176
  /**
package/dist/index.d.ts CHANGED
@@ -1098,11 +1098,11 @@ export interface CopilotCustomizationViewPayload {
1098
1098
  * server (verifier).
1099
1099
  *
1100
1100
  * Single source of truth for the `x-ms-device-*` header names and the
1101
- * HMAC-SHA-256 request-signature algorithm. Previously the same
1102
- * constants + function were copy-pasted in three places
1103
- * (extension `services/device/deviceAuth.ts`, core `device/deviceAuth.ts`,
1104
- * server `lib/auth/device-signature-guard.ts`) and kept in sync by
1105
- * comments alone. Server and extension now import from here.
1101
+ * request-signature algorithms. Previously the same constants +
1102
+ * functions were copy-pasted in three places (extension
1103
+ * `services/device/deviceAuth.ts`, core `device/deviceAuth.ts`, server
1104
+ * `lib/auth/device-signature-guard.ts`) and kept in sync by comments
1105
+ * alone. Server and extension now import from here.
1106
1106
  *
1107
1107
  * NOTE: `packages/serviceme-core/src/device/deviceAuth.ts` keeps its own
1108
1108
  * copy — ADL-003 forbids core → shared (and shared → core) so the core
@@ -1117,7 +1117,15 @@ export declare const DeviceAuthHeaders: {
1117
1117
  readonly signature: "x-ms-device-signature";
1118
1118
  readonly timestamp: "x-ms-device-timestamp";
1119
1119
  readonly secretVersion: "x-ms-device-secret-version";
1120
+ /** v2 only — algorithm self-declaration so the server can verify
1121
+ * both schemes during the legacy-client rollout window. */
1122
+ readonly sigAlg: "x-ms-device-sig-alg";
1123
+ /** v2 only — one-time value folded into the signature basis and
1124
+ * checked against a server-side replay cache. */
1125
+ readonly nonce: "x-ms-device-nonce";
1120
1126
  };
1127
+ /** v2 signature algorithm identifier carried in `x-ms-device-sig-alg`. */
1128
+ export declare const DEVICE_SIG_ALG_V2 = "hmac-sha256-v2";
1121
1129
  export interface DeviceRequestSignatureParams {
1122
1130
  method: string;
1123
1131
  path: string;
@@ -1126,8 +1134,12 @@ export interface DeviceRequestSignatureParams {
1126
1134
  secret: string;
1127
1135
  }
1128
1136
  /**
1129
- * Basis is `METHOD\nPATH\nTIMESTAMP\nBODY\nSECRET` (LF-joined, NOT JSON).
1130
- * Output is lowercase hex SHA-256.
1137
+ * Legacy (v1) basis: `METHOD\nPATH\nTIMESTAMP\nBODY\nSECRET`
1138
+ * (LF-joined, NOT JSON), hashed with a secret-suffix SHA-256.
1139
+ * Output is lowercase hex.
1140
+ *
1141
+ * Retained for backward compatibility with fielded extensions that
1142
+ * predate v2; new code should use `createDeviceRequestSignatureV2`.
1131
1143
  *
1132
1144
  * Uses `js-sha256` (pure JS, synchronous, browser + Node) instead of
1133
1145
  * `node:crypto` so this module stays importable from the webview (the
@@ -1135,6 +1147,30 @@ export interface DeviceRequestSignatureParams {
1135
1147
  * the vite/rollup build).
1136
1148
  */
1137
1149
  export declare function createDeviceRequestSignature(params: DeviceRequestSignatureParams): string;
1150
+ export interface DeviceRequestSignatureV2Params {
1151
+ method: string;
1152
+ /** Full request path INCLUDING the query string (e.g.
1153
+ * `/api/v1/tools/rtk/download?version=1.2.0&target=darwin-arm64`).
1154
+ * v2 signs the query so GET parameters cannot be substituted or
1155
+ * replayed independently of the signed basis. */
1156
+ path: string;
1157
+ timestamp: number;
1158
+ /** One-time value; the server tracks seen nonces per device and
1159
+ * rejects replays within the timestamp window. */
1160
+ nonce: string;
1161
+ body: string;
1162
+ secret: string;
1163
+ }
1164
+ /**
1165
+ * v2 basis: `METHOD\nPATH?QUERY\nTIMESTAMP\nNONCE\nBODY\nSECRET`
1166
+ * (LF-joined, NOT JSON), MACed with real HMAC-SHA-256 keyed by the
1167
+ * device secret. Output is lowercase hex.
1168
+ *
1169
+ * The client MUST build the exact query string it will send before
1170
+ * signing — the server verifies against the raw `request.url` search,
1171
+ * so the signed string and the wire URL have to match byte-for-byte.
1172
+ */
1173
+ export declare function createDeviceRequestSignatureV2(params: DeviceRequestSignatureV2Params): string;
1138
1174
  //#endregion
1139
1175
  //#region src/git-utils.d.ts
1140
1176
  /**
package/dist/index.js CHANGED
@@ -1728,11 +1728,11 @@ sha224.hmac = createNodeHmacMethod("sha224");
1728
1728
  * server (verifier).
1729
1729
  *
1730
1730
  * Single source of truth for the `x-ms-device-*` header names and the
1731
- * HMAC-SHA-256 request-signature algorithm. Previously the same
1732
- * constants + function were copy-pasted in three places
1733
- * (extension `services/device/deviceAuth.ts`, core `device/deviceAuth.ts`,
1734
- * server `lib/auth/device-signature-guard.ts`) and kept in sync by
1735
- * comments alone. Server and extension now import from here.
1731
+ * request-signature algorithms. Previously the same constants +
1732
+ * functions were copy-pasted in three places (extension
1733
+ * `services/device/deviceAuth.ts`, core `device/deviceAuth.ts`, server
1734
+ * `lib/auth/device-signature-guard.ts`) and kept in sync by comments
1735
+ * alone. Server and extension now import from here.
1736
1736
  *
1737
1737
  * NOTE: `packages/serviceme-core/src/device/deviceAuth.ts` keeps its own
1738
1738
  * copy — ADL-003 forbids core → shared (and shared → core) so the core
@@ -1746,11 +1746,23 @@ const DeviceAuthHeaders = {
1746
1746
  deviceSecret: "x-ms-device-secret",
1747
1747
  signature: "x-ms-device-signature",
1748
1748
  timestamp: "x-ms-device-timestamp",
1749
- secretVersion: "x-ms-device-secret-version"
1749
+ secretVersion: "x-ms-device-secret-version",
1750
+ /** v2 only — algorithm self-declaration so the server can verify
1751
+ * both schemes during the legacy-client rollout window. */
1752
+ sigAlg: "x-ms-device-sig-alg",
1753
+ /** v2 only — one-time value folded into the signature basis and
1754
+ * checked against a server-side replay cache. */
1755
+ nonce: "x-ms-device-nonce"
1750
1756
  };
1757
+ /** v2 signature algorithm identifier carried in `x-ms-device-sig-alg`. */
1758
+ const DEVICE_SIG_ALG_V2 = "hmac-sha256-v2";
1751
1759
  /**
1752
- * Basis is `METHOD\nPATH\nTIMESTAMP\nBODY\nSECRET` (LF-joined, NOT JSON).
1753
- * Output is lowercase hex SHA-256.
1760
+ * Legacy (v1) basis: `METHOD\nPATH\nTIMESTAMP\nBODY\nSECRET`
1761
+ * (LF-joined, NOT JSON), hashed with a secret-suffix SHA-256.
1762
+ * Output is lowercase hex.
1763
+ *
1764
+ * Retained for backward compatibility with fielded extensions that
1765
+ * predate v2; new code should use `createDeviceRequestSignatureV2`.
1754
1766
  *
1755
1767
  * Uses `js-sha256` (pure JS, synchronous, browser + Node) instead of
1756
1768
  * `node:crypto` so this module stays importable from the webview (the
@@ -1767,6 +1779,26 @@ function createDeviceRequestSignature(params) {
1767
1779
  ].join("\n");
1768
1780
  return sha256(basis);
1769
1781
  }
1782
+ /**
1783
+ * v2 basis: `METHOD\nPATH?QUERY\nTIMESTAMP\nNONCE\nBODY\nSECRET`
1784
+ * (LF-joined, NOT JSON), MACed with real HMAC-SHA-256 keyed by the
1785
+ * device secret. Output is lowercase hex.
1786
+ *
1787
+ * The client MUST build the exact query string it will send before
1788
+ * signing — the server verifies against the raw `request.url` search,
1789
+ * so the signed string and the wire URL have to match byte-for-byte.
1790
+ */
1791
+ function createDeviceRequestSignatureV2(params) {
1792
+ const basis = [
1793
+ params.method.toUpperCase(),
1794
+ params.path,
1795
+ String(params.timestamp),
1796
+ params.nonce,
1797
+ params.body,
1798
+ params.secret
1799
+ ].join("\n");
1800
+ return sha256.hmac(params.secret, basis);
1801
+ }
1770
1802
  //#endregion
1771
1803
  //#region src/git-utils.ts
1772
1804
  /**
@@ -2358,6 +2390,7 @@ exports.BUILTIN_PROVIDER_PRESETS = BUILTIN_PROVIDER_PRESETS;
2358
2390
  exports.ByomSettingsResponse = ByomSettingsResponse;
2359
2391
  exports.CERTIFICATE_BUNDLE_FORMATS = CERTIFICATE_BUNDLE_FORMATS;
2360
2392
  exports.CachedServerUrlResponse = CachedServerUrlResponse;
2393
+ exports.DEVICE_SIG_ALG_V2 = DEVICE_SIG_ALG_V2;
2361
2394
  exports.DeviceAuthHeaders = DeviceAuthHeaders;
2362
2395
  exports.GIT_REMOTE_HOST_ALIASES = GIT_REMOTE_HOST_ALIASES;
2363
2396
  exports.GetByomSettings = GetByomSettings;
@@ -2388,6 +2421,7 @@ exports.buildPresetModel = buildPresetModel;
2388
2421
  exports.checkGitHubOrgMembership = checkGitHubOrgMembership;
2389
2422
  exports.createConsoleLogger = createConsoleLogger;
2390
2423
  exports.createDeviceRequestSignature = createDeviceRequestSignature;
2424
+ exports.createDeviceRequestSignatureV2 = createDeviceRequestSignatureV2;
2391
2425
  exports.currencyForBaseUrl = currencyForBaseUrl;
2392
2426
  exports.effectiveAdapterType = effectiveAdapterType;
2393
2427
  exports.fetchGitHubUser = fetchGitHubUser;
package/dist/index.mjs CHANGED
@@ -1727,11 +1727,11 @@ sha224.hmac = createNodeHmacMethod("sha224");
1727
1727
  * server (verifier).
1728
1728
  *
1729
1729
  * Single source of truth for the `x-ms-device-*` header names and the
1730
- * HMAC-SHA-256 request-signature algorithm. Previously the same
1731
- * constants + function were copy-pasted in three places
1732
- * (extension `services/device/deviceAuth.ts`, core `device/deviceAuth.ts`,
1733
- * server `lib/auth/device-signature-guard.ts`) and kept in sync by
1734
- * comments alone. Server and extension now import from here.
1730
+ * request-signature algorithms. Previously the same constants +
1731
+ * functions were copy-pasted in three places (extension
1732
+ * `services/device/deviceAuth.ts`, core `device/deviceAuth.ts`, server
1733
+ * `lib/auth/device-signature-guard.ts`) and kept in sync by comments
1734
+ * alone. Server and extension now import from here.
1735
1735
  *
1736
1736
  * NOTE: `packages/serviceme-core/src/device/deviceAuth.ts` keeps its own
1737
1737
  * copy — ADL-003 forbids core → shared (and shared → core) so the core
@@ -1745,11 +1745,23 @@ const DeviceAuthHeaders = {
1745
1745
  deviceSecret: "x-ms-device-secret",
1746
1746
  signature: "x-ms-device-signature",
1747
1747
  timestamp: "x-ms-device-timestamp",
1748
- secretVersion: "x-ms-device-secret-version"
1748
+ secretVersion: "x-ms-device-secret-version",
1749
+ /** v2 only — algorithm self-declaration so the server can verify
1750
+ * both schemes during the legacy-client rollout window. */
1751
+ sigAlg: "x-ms-device-sig-alg",
1752
+ /** v2 only — one-time value folded into the signature basis and
1753
+ * checked against a server-side replay cache. */
1754
+ nonce: "x-ms-device-nonce"
1749
1755
  };
1756
+ /** v2 signature algorithm identifier carried in `x-ms-device-sig-alg`. */
1757
+ const DEVICE_SIG_ALG_V2 = "hmac-sha256-v2";
1750
1758
  /**
1751
- * Basis is `METHOD\nPATH\nTIMESTAMP\nBODY\nSECRET` (LF-joined, NOT JSON).
1752
- * Output is lowercase hex SHA-256.
1759
+ * Legacy (v1) basis: `METHOD\nPATH\nTIMESTAMP\nBODY\nSECRET`
1760
+ * (LF-joined, NOT JSON), hashed with a secret-suffix SHA-256.
1761
+ * Output is lowercase hex.
1762
+ *
1763
+ * Retained for backward compatibility with fielded extensions that
1764
+ * predate v2; new code should use `createDeviceRequestSignatureV2`.
1753
1765
  *
1754
1766
  * Uses `js-sha256` (pure JS, synchronous, browser + Node) instead of
1755
1767
  * `node:crypto` so this module stays importable from the webview (the
@@ -1766,6 +1778,26 @@ function createDeviceRequestSignature(params) {
1766
1778
  ].join("\n");
1767
1779
  return sha256(basis);
1768
1780
  }
1781
+ /**
1782
+ * v2 basis: `METHOD\nPATH?QUERY\nTIMESTAMP\nNONCE\nBODY\nSECRET`
1783
+ * (LF-joined, NOT JSON), MACed with real HMAC-SHA-256 keyed by the
1784
+ * device secret. Output is lowercase hex.
1785
+ *
1786
+ * The client MUST build the exact query string it will send before
1787
+ * signing — the server verifies against the raw `request.url` search,
1788
+ * so the signed string and the wire URL have to match byte-for-byte.
1789
+ */
1790
+ function createDeviceRequestSignatureV2(params) {
1791
+ const basis = [
1792
+ params.method.toUpperCase(),
1793
+ params.path,
1794
+ String(params.timestamp),
1795
+ params.nonce,
1796
+ params.body,
1797
+ params.secret
1798
+ ].join("\n");
1799
+ return sha256.hmac(params.secret, basis);
1800
+ }
1769
1801
  //#endregion
1770
1802
  //#region src/git-utils.ts
1771
1803
  /**
@@ -2353,4 +2385,4 @@ function safeJson(text, fallback) {
2353
2385
  }
2354
2386
  }
2355
2387
  //#endregion
2356
- export { BUILTIN_PROVIDER_PRESETS, ByomSettingsResponse, CERTIFICATE_BUNDLE_FORMATS, CachedServerUrlResponse, DeviceAuthHeaders, GIT_REMOTE_HOST_ALIASES, GetByomSettings, GetCachedServerUrl, GetServerProxyState, GetUtilityModels, LISTABLE_PRESET_MODELS, LogLevel, MEDALSOFT_NUGET_PRIVATE_SOURCE, MEDALSOFT_PRIVATE_GATEWAY_URL, MODEL_METADATA, NAMESPACE_ALIASES, NAMESPACE_ALIAS_FAMILY, PRESET_MODEL_FAMILIES, PROVIDER_BASE_URL_PRESETS, PROVIDER_CACHE_CONTROL_METADATA, ServerProxyStateResponse, SetCacheControlEnabled, SetServerProxyAllowOverride, SetServerProxyEnabled, UpdateUtilityModels, UtilityModelsResponse, WebviewMessageType, __internal, asAbortSignal, buildGitHubLocalEmail, buildPresetModel, checkGitHubOrgMembership, createConsoleLogger, createDeviceRequestSignature, currencyForBaseUrl, effectiveAdapterType, fetchGitHubUser, getBuiltinProviderPreset, getGitHubOrgMembership, getPresetModelDisplayName, getProviderBaseUrlPresets, isGitHubLocalEmail, isProviderCacheControlAware, isValidCanonicalSlug, isWholePackageInstall, listPresetModelGroups, lookupModelMetadata, normalizeCanonicalSlug, normalizeErrorForLog, normalizeGitUrl, parsePayload, protocolForBaseUrl, registrationIdFromPackageId, resolvePrimaryEmail, safeJson, unionProviderModelWithPreset };
2388
+ export { BUILTIN_PROVIDER_PRESETS, ByomSettingsResponse, CERTIFICATE_BUNDLE_FORMATS, CachedServerUrlResponse, DEVICE_SIG_ALG_V2, DeviceAuthHeaders, GIT_REMOTE_HOST_ALIASES, GetByomSettings, GetCachedServerUrl, GetServerProxyState, GetUtilityModels, LISTABLE_PRESET_MODELS, LogLevel, MEDALSOFT_NUGET_PRIVATE_SOURCE, MEDALSOFT_PRIVATE_GATEWAY_URL, MODEL_METADATA, NAMESPACE_ALIASES, NAMESPACE_ALIAS_FAMILY, PRESET_MODEL_FAMILIES, PROVIDER_BASE_URL_PRESETS, PROVIDER_CACHE_CONTROL_METADATA, ServerProxyStateResponse, SetCacheControlEnabled, SetServerProxyAllowOverride, SetServerProxyEnabled, UpdateUtilityModels, UtilityModelsResponse, WebviewMessageType, __internal, asAbortSignal, buildGitHubLocalEmail, buildPresetModel, checkGitHubOrgMembership, createConsoleLogger, createDeviceRequestSignature, createDeviceRequestSignatureV2, currencyForBaseUrl, effectiveAdapterType, fetchGitHubUser, getBuiltinProviderPreset, getGitHubOrgMembership, getPresetModelDisplayName, getProviderBaseUrlPresets, isGitHubLocalEmail, isProviderCacheControlAware, isValidCanonicalSlug, isWholePackageInstall, listPresetModelGroups, lookupModelMetadata, normalizeCanonicalSlug, normalizeErrorForLog, normalizeGitUrl, parsePayload, protocolForBaseUrl, registrationIdFromPackageId, resolvePrimaryEmail, safeJson, unionProviderModelWithPreset };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serviceme/devtools-shared",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "Shared webview↔extension message contracts and cross-package data models used by SERVICEME.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "repository": {