@microwiseai/snapshot 0.3.66 → 0.3.70-dev.0
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/commands/access.d.ts.map +1 -1
- package/dist/commands/access.js +6 -0
- package/dist/commands/access.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +14 -24
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +8 -1
- package/dist/commands/publish.js.map +1 -1
- package/dist/lib/access-sync.d.ts +32 -0
- package/dist/lib/access-sync.d.ts.map +1 -1
- package/dist/lib/access-sync.js +96 -45
- package/dist/lib/access-sync.js.map +1 -1
- package/dist/lib/access-sync.test.d.ts +2 -0
- package/dist/lib/access-sync.test.d.ts.map +1 -0
- package/dist/lib/access-sync.test.js +224 -0
- package/dist/lib/access-sync.test.js.map +1 -0
- package/dist/lib/auth-flow.test.js +80 -141
- package/dist/lib/auth-flow.test.js.map +1 -1
- package/dist/lib/config.d.ts +25 -10
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +52 -77
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.js +2 -3
- package/dist/lib/config.test.js.map +1 -1
- package/dist/lib/prerequisites.d.ts.map +1 -1
- package/dist/lib/prerequisites.js +6 -4
- package/dist/lib/prerequisites.js.map +1 -1
- package/package.json +1 -3
package/dist/lib/access-sync.js
CHANGED
|
@@ -6,8 +6,59 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import chalk from 'chalk';
|
|
8
8
|
import { LICENSE_API_URL, GITLAB_GROUP_ID, REGISTRY_PROXY_URL } from './config.js';
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the admin API key from the environment.
|
|
11
|
+
*
|
|
12
|
+
* LICENSE_API_ADMIN_KEY is required. There is intentionally NO fallback —
|
|
13
|
+
* a missing key must fail loudly rather than silently using a weak default.
|
|
14
|
+
*/
|
|
15
|
+
function getAdminApiKey() {
|
|
16
|
+
const key = process.env.LICENSE_API_ADMIN_KEY;
|
|
17
|
+
if (!key) {
|
|
18
|
+
throw new Error('LICENSE_API_ADMIN_KEY environment variable is required for package access sync. ' +
|
|
19
|
+
'Set it before running access sync.');
|
|
20
|
+
}
|
|
21
|
+
return key;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the effective auth mode.
|
|
25
|
+
* Precedence: explicit option > SNAPSHOT_ACCESS_AUTH_MODE env > 'gitlab'.
|
|
26
|
+
* Default is 'gitlab' (STAGE2 cutover): access-rule writes authenticate via
|
|
27
|
+
* GitLab namespace ownership. Set authMode/env to 'admin-key' or 'dual' for the
|
|
28
|
+
* transitional legacy path.
|
|
29
|
+
*/
|
|
30
|
+
function resolveAuthMode(explicit) {
|
|
31
|
+
const candidate = explicit ?? process.env.SNAPSHOT_ACCESS_AUTH_MODE;
|
|
32
|
+
if (candidate === 'gitlab' || candidate === 'dual' || candidate === 'admin-key') {
|
|
33
|
+
return candidate;
|
|
34
|
+
}
|
|
35
|
+
if (candidate) {
|
|
36
|
+
console.warn(chalk.yellow(` Warning: unknown SNAPSHOT_ACCESS_AUTH_MODE "${candidate}", falling back to "gitlab".`));
|
|
37
|
+
}
|
|
38
|
+
return 'gitlab';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Build the auth headers for a license-api write call from the resolved auth
|
|
42
|
+
* context. Throws loudly when a required credential is missing — fail-closed,
|
|
43
|
+
* never silently drop authentication.
|
|
44
|
+
*/
|
|
45
|
+
function buildAuthHeaders(auth) {
|
|
46
|
+
const headers = {};
|
|
47
|
+
const needsGitlab = auth.mode === 'gitlab' || auth.mode === 'dual';
|
|
48
|
+
const needsAdminKey = auth.mode === 'admin-key' || auth.mode === 'dual';
|
|
49
|
+
if (needsGitlab) {
|
|
50
|
+
if (!auth.gitlabToken) {
|
|
51
|
+
throw new Error(`Access sync auth mode "${auth.mode}" requires a GitLab token but none was provided. ` +
|
|
52
|
+
'Ensure gitlab-config is set or GITLAB_TOKEN is exported (the same token used by gitlab-publish).');
|
|
53
|
+
}
|
|
54
|
+
headers['Authorization'] = `Bearer ${auth.gitlabToken}`;
|
|
55
|
+
}
|
|
56
|
+
if (needsAdminKey) {
|
|
57
|
+
// getAdminApiKey() throws loudly if LICENSE_API_ADMIN_KEY is unset.
|
|
58
|
+
headers['X-Admin-Api-Key'] = getAdminApiKey();
|
|
59
|
+
}
|
|
60
|
+
return headers;
|
|
61
|
+
}
|
|
11
62
|
/**
|
|
12
63
|
* Parse package name into scope and name
|
|
13
64
|
* @example "@ist/loggable-cli" -> { scope: "@ist", name: "loggable-cli" }
|
|
@@ -42,33 +93,20 @@ function getProductId(access) {
|
|
|
42
93
|
return undefined;
|
|
43
94
|
}
|
|
44
95
|
/**
|
|
45
|
-
*
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (!data.success || !data.data?.items)
|
|
57
|
-
return null;
|
|
58
|
-
const existing = data.data.items.find(item => item.package_name === packageName);
|
|
59
|
-
return existing ? { id: existing.id } : null;
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Register or update a package with license-api (upsert)
|
|
96
|
+
* Register a package with license-api via a single idempotent upsert.
|
|
97
|
+
*
|
|
98
|
+
* Uses POST /admin/package-access/with-deps. The (scope, packageName) pair is a
|
|
99
|
+
* unique key on the license-api side, so this call is idempotent — repeated
|
|
100
|
+
* calls update the existing rule instead of creating duplicates. This replaces
|
|
101
|
+
* the previous non-atomic find-then-create (GET + PUT/POST) flow.
|
|
102
|
+
*
|
|
103
|
+
* `dependencies` is intentionally sent as an empty array: access-sync already
|
|
104
|
+
* enumerates the full (transitive) package set on the client side, so the
|
|
105
|
+
* server-side automatic dependency resolution must be disabled to avoid
|
|
106
|
+
* duplicate/conflicting rule creation.
|
|
67
107
|
*/
|
|
68
|
-
async function registerPackage(rule) {
|
|
108
|
+
async function registerPackage(rule, authHeaders) {
|
|
69
109
|
try {
|
|
70
|
-
// Check if already exists
|
|
71
|
-
const existing = await findExistingRule(rule.scope, rule.packageName);
|
|
72
110
|
const body = {
|
|
73
111
|
scope: rule.scope,
|
|
74
112
|
packageName: rule.packageName,
|
|
@@ -77,24 +115,16 @@ async function registerPackage(rule) {
|
|
|
77
115
|
description: rule.description,
|
|
78
116
|
requiredProductIds: rule.requiredProductIds,
|
|
79
117
|
parentPackage: rule.parentPackage,
|
|
118
|
+
// Disable server-side auto dependency resolution — the client enumerates
|
|
119
|
+
// all packages itself and registers each one individually.
|
|
120
|
+
dependencies: [],
|
|
80
121
|
};
|
|
81
|
-
|
|
82
|
-
let method;
|
|
83
|
-
if (existing) {
|
|
84
|
-
// Update existing rule
|
|
85
|
-
url = `${LICENSE_API_URL}/admin/package-access/${existing.id}`;
|
|
86
|
-
method = 'PUT';
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
// Create new rule
|
|
90
|
-
url = `${LICENSE_API_URL}/admin/package-access`;
|
|
91
|
-
method = 'POST';
|
|
92
|
-
}
|
|
122
|
+
const url = `${LICENSE_API_URL}/admin/package-access/with-deps`;
|
|
93
123
|
const response = await fetch(url, {
|
|
94
|
-
method,
|
|
124
|
+
method: 'POST',
|
|
95
125
|
headers: {
|
|
96
126
|
'Content-Type': 'application/json',
|
|
97
|
-
|
|
127
|
+
...authHeaders,
|
|
98
128
|
},
|
|
99
129
|
body: JSON.stringify(body),
|
|
100
130
|
});
|
|
@@ -102,7 +132,7 @@ async function registerPackage(rule) {
|
|
|
102
132
|
return true;
|
|
103
133
|
}
|
|
104
134
|
const error = await response.json().catch(() => ({}));
|
|
105
|
-
console.error(chalk.yellow(` Warning: Failed to
|
|
135
|
+
console.error(chalk.yellow(` Warning: Failed to upsert ${rule.scope}/${rule.packageName}: ${JSON.stringify(error)}`));
|
|
106
136
|
return false;
|
|
107
137
|
}
|
|
108
138
|
catch (error) {
|
|
@@ -178,8 +208,15 @@ export async function syncPackageAccess(snapshot, options = {}) {
|
|
|
178
208
|
};
|
|
179
209
|
const accessLevel = getAccessLevel(snapshot.access);
|
|
180
210
|
const productId = getProductId(snapshot.access);
|
|
211
|
+
// Resolve auth ONCE up front so a missing credential fails loudly before any
|
|
212
|
+
// partial writes happen. Skipped in dry-run (no network calls are made).
|
|
213
|
+
const authMode = resolveAuthMode(options.authMode);
|
|
214
|
+
const authHeaders = dryRun
|
|
215
|
+
? {}
|
|
216
|
+
: buildAuthHeaders({ mode: authMode, gitlabToken: options.gitlabToken });
|
|
181
217
|
console.log(chalk.cyan(`\nSyncing package access for ${snapshot.name}...`));
|
|
182
218
|
console.log(chalk.dim(` Access level: ${accessLevel}`));
|
|
219
|
+
console.log(chalk.dim(` Auth mode: ${authMode}`));
|
|
183
220
|
// 1. Extract direct packages from snapshot
|
|
184
221
|
const directPackages = extractPackagesFromSnapshot(snapshot);
|
|
185
222
|
if (verbose) {
|
|
@@ -198,6 +235,16 @@ export async function syncPackageAccess(snapshot, options = {}) {
|
|
|
198
235
|
console.log(chalk.dim(` Total packages (with deps): ${allPackages.length}`));
|
|
199
236
|
}
|
|
200
237
|
}
|
|
238
|
+
// 2b. Always register the snapshot's own artifact package.
|
|
239
|
+
//
|
|
240
|
+
// Member packages are registered above, but the snapshot artifact itself
|
|
241
|
+
// (e.g. "@ist/testing") was previously never registered. As a result the
|
|
242
|
+
// registry proxy had no access rule for the snapshot artifact and rejected
|
|
243
|
+
// downloads (e.g. testing -> 401). Register the snapshot's own package with
|
|
244
|
+
// the access level declared in snapshot.json so the proxy knows it.
|
|
245
|
+
if (snapshot.name && !allPackages.includes(snapshot.name)) {
|
|
246
|
+
allPackages.unshift(snapshot.name);
|
|
247
|
+
}
|
|
201
248
|
// 3. Register each package
|
|
202
249
|
console.log(chalk.dim(` Registering ${allPackages.length} packages...`));
|
|
203
250
|
for (const pkg of allPackages) {
|
|
@@ -206,13 +253,17 @@ export async function syncPackageAccess(snapshot, options = {}) {
|
|
|
206
253
|
result.skipped.push(pkg);
|
|
207
254
|
continue;
|
|
208
255
|
}
|
|
256
|
+
const isSelf = pkg === snapshot.name;
|
|
209
257
|
const rule = {
|
|
210
258
|
scope: parsed.scope,
|
|
211
259
|
packageName: parsed.name,
|
|
212
260
|
accessLevel,
|
|
213
261
|
priority: 100,
|
|
214
|
-
description:
|
|
215
|
-
|
|
262
|
+
description: isSelf
|
|
263
|
+
? `Snapshot artifact ${snapshot.name}`
|
|
264
|
+
: `Auto-synced from ${snapshot.name}`,
|
|
265
|
+
// The snapshot's own package has no parent; member packages point to it.
|
|
266
|
+
parentPackage: isSelf ? undefined : snapshot.name,
|
|
216
267
|
};
|
|
217
268
|
if (accessLevel === 'licensed' && productId) {
|
|
218
269
|
rule.requiredProductIds = productId;
|
|
@@ -222,7 +273,7 @@ export async function syncPackageAccess(snapshot, options = {}) {
|
|
|
222
273
|
result.registered.push(pkg);
|
|
223
274
|
}
|
|
224
275
|
else {
|
|
225
|
-
const success = await registerPackage(rule);
|
|
276
|
+
const success = await registerPackage(rule, authHeaders);
|
|
226
277
|
if (success) {
|
|
227
278
|
result.registered.push(pkg);
|
|
228
279
|
if (verbose) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-sync.js","sourceRoot":"","sources":["../../src/lib/access-sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEnF
|
|
1
|
+
{"version":3,"file":"access-sync.js","sourceRoot":"","sources":["../../src/lib/access-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-sync.test.d.ts","sourceRoot":"","sources":["../../src/lib/access-sync.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { syncPackageAccess } from './access-sync.js';
|
|
3
|
+
import { LICENSE_API_URL } from './config.js';
|
|
4
|
+
/**
|
|
5
|
+
* Unit tests for access-sync.
|
|
6
|
+
*
|
|
7
|
+
* `fetch` is fully mocked — no real license-api write calls are made.
|
|
8
|
+
* Transitive resolution is disabled so the only network surface is the
|
|
9
|
+
* idempotent upsert (POST /admin/package-access/with-deps).
|
|
10
|
+
*/
|
|
11
|
+
const UPSERT_URL = `${LICENSE_API_URL}/admin/package-access/with-deps`;
|
|
12
|
+
function makeFetchMock() {
|
|
13
|
+
return vi.fn(async () => ({
|
|
14
|
+
ok: true,
|
|
15
|
+
json: async () => ({}),
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
/** Extract parsed bodies of every upsert call recorded by the fetch mock. */
|
|
19
|
+
function upsertBodies(fetchMock) {
|
|
20
|
+
return fetchMock.mock.calls
|
|
21
|
+
.filter((call) => call[0] === UPSERT_URL)
|
|
22
|
+
.map((call) => JSON.parse(call[1].body));
|
|
23
|
+
}
|
|
24
|
+
/** Extract the headers of every upsert call recorded by the fetch mock. */
|
|
25
|
+
function upsertHeaders(fetchMock) {
|
|
26
|
+
return fetchMock.mock.calls
|
|
27
|
+
.filter((call) => call[0] === UPSERT_URL)
|
|
28
|
+
.map((call) => call[1].headers);
|
|
29
|
+
}
|
|
30
|
+
describe('syncPackageAccess - snapshot own package registration', () => {
|
|
31
|
+
let originalFetch;
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
originalFetch = globalThis.fetch;
|
|
34
|
+
process.env.LICENSE_API_ADMIN_KEY = 'test-admin-key';
|
|
35
|
+
vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
36
|
+
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
37
|
+
});
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
globalThis.fetch = originalFetch;
|
|
40
|
+
delete process.env.LICENSE_API_ADMIN_KEY;
|
|
41
|
+
vi.restoreAllMocks();
|
|
42
|
+
});
|
|
43
|
+
it("registers the snapshot's own package with its declared access level", async () => {
|
|
44
|
+
const fetchMock = makeFetchMock();
|
|
45
|
+
globalThis.fetch = fetchMock;
|
|
46
|
+
const snapshot = {
|
|
47
|
+
name: '@ist/testing',
|
|
48
|
+
version: '0.1.0',
|
|
49
|
+
access: 'authenticated',
|
|
50
|
+
install: {
|
|
51
|
+
'gitlab-install': {
|
|
52
|
+
'@ist/member-a': '1.0.0',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
const result = await syncPackageAccess(snapshot, { includeTransitive: false, gitlabToken: 'glpat-test' });
|
|
57
|
+
const bodies = upsertBodies(fetchMock);
|
|
58
|
+
const self = bodies.find((b) => b.scope === '@ist' && b.packageName === 'testing');
|
|
59
|
+
expect(self).toBeDefined();
|
|
60
|
+
expect(self.accessLevel).toBe('authenticated');
|
|
61
|
+
// Snapshot's own package has no parent.
|
|
62
|
+
expect(self.parentPackage).toBeUndefined();
|
|
63
|
+
// Still uses the idempotent with-deps upsert with empty dependencies.
|
|
64
|
+
expect(self.dependencies).toEqual([]);
|
|
65
|
+
// Member package is registered too and points to the snapshot as parent.
|
|
66
|
+
const member = bodies.find((b) => b.packageName === 'member-a');
|
|
67
|
+
expect(member).toBeDefined();
|
|
68
|
+
expect(member.parentPackage).toBe('@ist/testing');
|
|
69
|
+
expect(result.registered).toContain('@ist/testing');
|
|
70
|
+
});
|
|
71
|
+
it('maps public access for the snapshot own package', async () => {
|
|
72
|
+
const fetchMock = makeFetchMock();
|
|
73
|
+
globalThis.fetch = fetchMock;
|
|
74
|
+
const snapshot = {
|
|
75
|
+
name: '@ist/free',
|
|
76
|
+
version: '1.0.0',
|
|
77
|
+
access: 'public',
|
|
78
|
+
install: {},
|
|
79
|
+
};
|
|
80
|
+
await syncPackageAccess(snapshot, { includeTransitive: false, gitlabToken: 'glpat-test' });
|
|
81
|
+
const self = upsertBodies(fetchMock).find((b) => b.packageName === 'free');
|
|
82
|
+
expect(self).toBeDefined();
|
|
83
|
+
expect(self.accessLevel).toBe('public');
|
|
84
|
+
});
|
|
85
|
+
it('maps licensed access and propagates productId for the snapshot own package', async () => {
|
|
86
|
+
const fetchMock = makeFetchMock();
|
|
87
|
+
globalThis.fetch = fetchMock;
|
|
88
|
+
const snapshot = {
|
|
89
|
+
name: '@ist/pro',
|
|
90
|
+
version: '1.0.0',
|
|
91
|
+
access: { type: 'licensed', productId: 'prod_123' },
|
|
92
|
+
install: {},
|
|
93
|
+
};
|
|
94
|
+
await syncPackageAccess(snapshot, { includeTransitive: false, gitlabToken: 'glpat-test' });
|
|
95
|
+
const self = upsertBodies(fetchMock).find((b) => b.packageName === 'pro');
|
|
96
|
+
expect(self).toBeDefined();
|
|
97
|
+
expect(self.accessLevel).toBe('licensed');
|
|
98
|
+
expect(self.requiredProductIds).toBe('prod_123');
|
|
99
|
+
});
|
|
100
|
+
it('does not duplicate when the snapshot package also appears as a member', async () => {
|
|
101
|
+
const fetchMock = makeFetchMock();
|
|
102
|
+
globalThis.fetch = fetchMock;
|
|
103
|
+
const snapshot = {
|
|
104
|
+
name: '@ist/testing',
|
|
105
|
+
version: '0.1.0',
|
|
106
|
+
access: 'authenticated',
|
|
107
|
+
install: {
|
|
108
|
+
'gitlab-install': {
|
|
109
|
+
'@ist/testing': '0.1.0',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
await syncPackageAccess(snapshot, { includeTransitive: false, gitlabToken: 'glpat-test' });
|
|
114
|
+
const selfHits = upsertBodies(fetchMock).filter((b) => b.scope === '@ist' && b.packageName === 'testing');
|
|
115
|
+
expect(selfHits).toHaveLength(1);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('syncPackageAccess - cutover-safe auth modes', () => {
|
|
119
|
+
let originalFetch;
|
|
120
|
+
const snapshot = {
|
|
121
|
+
name: '@ist/free',
|
|
122
|
+
version: '1.0.0',
|
|
123
|
+
access: 'public',
|
|
124
|
+
install: {},
|
|
125
|
+
};
|
|
126
|
+
beforeEach(() => {
|
|
127
|
+
originalFetch = globalThis.fetch;
|
|
128
|
+
process.env.LICENSE_API_ADMIN_KEY = 'test-admin-key';
|
|
129
|
+
delete process.env.SNAPSHOT_ACCESS_AUTH_MODE;
|
|
130
|
+
vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
131
|
+
vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
132
|
+
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
133
|
+
});
|
|
134
|
+
afterEach(() => {
|
|
135
|
+
globalThis.fetch = originalFetch;
|
|
136
|
+
delete process.env.LICENSE_API_ADMIN_KEY;
|
|
137
|
+
delete process.env.SNAPSHOT_ACCESS_AUTH_MODE;
|
|
138
|
+
vi.restoreAllMocks();
|
|
139
|
+
});
|
|
140
|
+
it("defaults to gitlab mode (Bearer, no admin key) — STAGE2 cutover", async () => {
|
|
141
|
+
const fetchMock = makeFetchMock();
|
|
142
|
+
globalThis.fetch = fetchMock;
|
|
143
|
+
// No authMode / no env → default is now 'gitlab'.
|
|
144
|
+
await syncPackageAccess(snapshot, {
|
|
145
|
+
includeTransitive: false,
|
|
146
|
+
gitlabToken: 'glpat-default',
|
|
147
|
+
});
|
|
148
|
+
const headers = upsertHeaders(fetchMock)[0];
|
|
149
|
+
expect(headers['Authorization']).toBe('Bearer glpat-default');
|
|
150
|
+
expect(headers['X-Admin-Api-Key']).toBeUndefined();
|
|
151
|
+
});
|
|
152
|
+
it("admin-key mode (explicit) sends legacy header only — transitional fallback", async () => {
|
|
153
|
+
const fetchMock = makeFetchMock();
|
|
154
|
+
globalThis.fetch = fetchMock;
|
|
155
|
+
await syncPackageAccess(snapshot, {
|
|
156
|
+
includeTransitive: false,
|
|
157
|
+
authMode: 'admin-key',
|
|
158
|
+
});
|
|
159
|
+
const headers = upsertHeaders(fetchMock)[0];
|
|
160
|
+
expect(headers['X-Admin-Api-Key']).toBe('test-admin-key');
|
|
161
|
+
expect(headers['Authorization']).toBeUndefined();
|
|
162
|
+
});
|
|
163
|
+
it("fails closed: default (gitlab) without a token throws before any write", async () => {
|
|
164
|
+
const fetchMock = makeFetchMock();
|
|
165
|
+
globalThis.fetch = fetchMock;
|
|
166
|
+
await expect(syncPackageAccess(snapshot, { includeTransitive: false })).rejects.toThrow(/requires a GitLab token/);
|
|
167
|
+
expect(upsertBodies(fetchMock)).toHaveLength(0);
|
|
168
|
+
});
|
|
169
|
+
it("gitlab mode sends GitLab token as Bearer and drops the admin key", async () => {
|
|
170
|
+
const fetchMock = makeFetchMock();
|
|
171
|
+
globalThis.fetch = fetchMock;
|
|
172
|
+
await syncPackageAccess(snapshot, {
|
|
173
|
+
includeTransitive: false,
|
|
174
|
+
authMode: 'gitlab',
|
|
175
|
+
gitlabToken: 'glpat-xyz',
|
|
176
|
+
});
|
|
177
|
+
const headers = upsertHeaders(fetchMock)[0];
|
|
178
|
+
expect(headers['Authorization']).toBe('Bearer glpat-xyz');
|
|
179
|
+
expect(headers['X-Admin-Api-Key']).toBeUndefined();
|
|
180
|
+
});
|
|
181
|
+
it("dual mode sends BOTH headers during the transition window", async () => {
|
|
182
|
+
const fetchMock = makeFetchMock();
|
|
183
|
+
globalThis.fetch = fetchMock;
|
|
184
|
+
await syncPackageAccess(snapshot, {
|
|
185
|
+
includeTransitive: false,
|
|
186
|
+
authMode: 'dual',
|
|
187
|
+
gitlabToken: 'glpat-xyz',
|
|
188
|
+
});
|
|
189
|
+
const headers = upsertHeaders(fetchMock)[0];
|
|
190
|
+
expect(headers['Authorization']).toBe('Bearer glpat-xyz');
|
|
191
|
+
expect(headers['X-Admin-Api-Key']).toBe('test-admin-key');
|
|
192
|
+
});
|
|
193
|
+
it("SNAPSHOT_ACCESS_AUTH_MODE env selects the mode when no explicit option", async () => {
|
|
194
|
+
process.env.SNAPSHOT_ACCESS_AUTH_MODE = 'gitlab';
|
|
195
|
+
const fetchMock = makeFetchMock();
|
|
196
|
+
globalThis.fetch = fetchMock;
|
|
197
|
+
await syncPackageAccess(snapshot, {
|
|
198
|
+
includeTransitive: false,
|
|
199
|
+
gitlabToken: 'glpat-env',
|
|
200
|
+
});
|
|
201
|
+
const headers = upsertHeaders(fetchMock)[0];
|
|
202
|
+
expect(headers['Authorization']).toBe('Bearer glpat-env');
|
|
203
|
+
});
|
|
204
|
+
it("fails closed: gitlab mode without a token throws before any write", async () => {
|
|
205
|
+
const fetchMock = makeFetchMock();
|
|
206
|
+
globalThis.fetch = fetchMock;
|
|
207
|
+
await expect(syncPackageAccess(snapshot, { includeTransitive: false, authMode: 'gitlab' })).rejects.toThrow(/requires a GitLab token/);
|
|
208
|
+
// No write should have happened.
|
|
209
|
+
expect(upsertBodies(fetchMock)).toHaveLength(0);
|
|
210
|
+
});
|
|
211
|
+
it("dry-run makes no network calls and needs no credentials", async () => {
|
|
212
|
+
delete process.env.LICENSE_API_ADMIN_KEY;
|
|
213
|
+
const fetchMock = makeFetchMock();
|
|
214
|
+
globalThis.fetch = fetchMock;
|
|
215
|
+
const result = await syncPackageAccess(snapshot, {
|
|
216
|
+
includeTransitive: false,
|
|
217
|
+
dryRun: true,
|
|
218
|
+
authMode: 'gitlab',
|
|
219
|
+
});
|
|
220
|
+
expect(upsertBodies(fetchMock)).toHaveLength(0);
|
|
221
|
+
expect(result.registered).toContain('@ist/free');
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
//# sourceMappingURL=access-sync.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-sync.test.js","sourceRoot":"","sources":["../../src/lib/access-sync.test.ts"],"names":[],"mappings":"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"}
|