@synapseone/sdk 0.9.0-dev.77 → 0.9.0-dev.79

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/iam.d.ts CHANGED
@@ -164,11 +164,30 @@ export declare class IamService {
164
164
  revokeApiKey(keyId: string): Promise<unknown>;
165
165
  listApiKeys(accountId: string): Promise<unknown>;
166
166
  verifyApiKey(apiKey: string): Promise<unknown>;
167
+ /** Rotate a key: returns the new secret once; the old key stays valid for `graceSeconds` (0 = revoke now). */
168
+ rotateApiKey(keyId: string, graceSeconds?: number): Promise<{
169
+ id: string;
170
+ apiKey: string;
171
+ prefix: string;
172
+ rotatedFrom: string;
173
+ oldKeyExpiresAt: string;
174
+ }>;
175
+ setOrgAdmin(userId: string, isOrgAdmin: boolean): Promise<unknown>;
176
+ managedPolicies(): Promise<{
177
+ name: string;
178
+ description: string;
179
+ document: any;
180
+ }[]>;
181
+ /** Instantiate an AWS-style managed policy (e.g. `ReadOnlyAccess`) in an account. */
182
+ createManagedPolicy(accountId: string, slug: string, managed: string, description?: string): Promise<unknown>;
167
183
  createServiceAccount(accountId: string, slug: string, description?: string): Promise<unknown>;
168
184
  listServiceAccounts(accountId: string): Promise<unknown>;
169
185
  serviceAccountToken(saId: string, scopes?: string[]): Promise<{
170
186
  accessToken: string;
171
187
  }>;
188
+ serviceAccountRoles(saId: string): Promise<unknown>;
189
+ assignServiceAccountRole(saId: string, roleId: string): Promise<unknown>;
190
+ unassignServiceAccountRole(saId: string, roleId: string): Promise<unknown>;
172
191
  usageSummary(filter?: {
173
192
  from?: string | Date;
174
193
  to?: string | Date;
package/dist/iam.js CHANGED
@@ -185,6 +185,23 @@ class IamService {
185
185
  verifyApiKey(apiKey) {
186
186
  return this.http.req(`/v1/keys/verify`, { method: 'POST', body: JSON.stringify({ apiKey }) });
187
187
  }
188
+ /** Rotate a key: returns the new secret once; the old key stays valid for `graceSeconds` (0 = revoke now). */
189
+ rotateApiKey(keyId, graceSeconds = 0) {
190
+ return this.http.req(`/v1/keys/${encodeURIComponent(keyId)}/rotate`, { method: 'POST', body: JSON.stringify({ graceSeconds }) });
191
+ }
192
+ // ---- org administrators & managed policies ----
193
+ setOrgAdmin(userId, isOrgAdmin) {
194
+ return this.http.req(`/v1/users/${encodeURIComponent(userId)}/org-admin`, { method: 'PUT', body: JSON.stringify({ isOrgAdmin }) });
195
+ }
196
+ managedPolicies() {
197
+ return this.http.req('/v1/managed-policies');
198
+ }
199
+ /** Instantiate an AWS-style managed policy (e.g. `ReadOnlyAccess`) in an account. */
200
+ createManagedPolicy(accountId, slug, managed, description) {
201
+ return this.http.req(`/v1/accounts/${encodeURIComponent(accountId)}/policies`, {
202
+ method: 'POST', body: JSON.stringify({ slug, managed, ...(description ? { description } : {}) }),
203
+ });
204
+ }
188
205
  // ---- service accounts ----
189
206
  createServiceAccount(accountId, slug, description = '') {
190
207
  return this.http.req(`/v1/accounts/${encodeURIComponent(accountId)}/service-accounts`, { method: 'POST', body: JSON.stringify({ slug, description }) });
@@ -198,6 +215,15 @@ class IamService {
198
215
  body: JSON.stringify(scopes === undefined ? {} : { scopes }),
199
216
  });
200
217
  }
218
+ serviceAccountRoles(saId) {
219
+ return this.http.req(`/v1/service-accounts/${encodeURIComponent(saId)}/roles`);
220
+ }
221
+ assignServiceAccountRole(saId, roleId) {
222
+ return this.http.req(`/v1/service-accounts/${encodeURIComponent(saId)}/roles`, { method: 'POST', body: JSON.stringify({ roleId }) });
223
+ }
224
+ unassignServiceAccountRole(saId, roleId) {
225
+ return this.http.req(`/v1/service-accounts/${encodeURIComponent(saId)}/roles/${encodeURIComponent(roleId)}`, { method: 'DELETE' });
226
+ }
201
227
  // ---- usage & telemetry ----
202
228
  usageSummary(filter) {
203
229
  const qs = new URLSearchParams();
@@ -666,3 +666,42 @@ function payload(method, path, body) {
666
666
  }
667
667
  });
668
668
  });
669
+ (0, node_test_1.describe)('IAM token management', () => {
670
+ (0, node_test_1.it)('rotation, org admins, managed policies and service-account roles', async () => {
671
+ const hits = [];
672
+ const server = node_http_1.default.createServer((req, res) => {
673
+ const chunks = [];
674
+ req.on('data', (c) => chunks.push(Buffer.from(c)));
675
+ req.on('end', () => {
676
+ hits.push({ method: req.method || 'GET', path: req.url || '/', body: Buffer.concat(chunks) });
677
+ res.setHeader('Content-Type', 'application/json');
678
+ res.end(JSON.stringify({ ok: true }));
679
+ });
680
+ });
681
+ await new Promise((resolve) => server.listen(0, '127.0.0.1', () => resolve()));
682
+ const a = server.address();
683
+ const c = new index_1.SynapseOneClient({ baseUrl: `http://127.0.0.1:${typeof a === 'object' && a ? a.port : 0}`, token: 'T' });
684
+ const last = () => hits[hits.length - 1];
685
+ try {
686
+ await c.iam.rotateApiKey('k1', 300);
687
+ strict_1.default.equal(last().path, '/v1/keys/k1/rotate');
688
+ strict_1.default.deepEqual(JSON.parse(last().body.toString()), { graceSeconds: 300 });
689
+ await c.iam.setOrgAdmin('u1', true);
690
+ strict_1.default.equal(last().method, 'PUT');
691
+ strict_1.default.deepEqual(JSON.parse(last().body.toString()), { isOrgAdmin: true });
692
+ await c.iam.managedPolicies();
693
+ strict_1.default.equal(last().path, '/v1/managed-policies');
694
+ await c.iam.createManagedPolicy('acc1', 'readers', 'ReadOnlyAccess');
695
+ strict_1.default.deepEqual(JSON.parse(last().body.toString()), { slug: 'readers', managed: 'ReadOnlyAccess' });
696
+ await c.iam.assignServiceAccountRole('sa1', 'r1');
697
+ strict_1.default.equal(last().path, '/v1/service-accounts/sa1/roles');
698
+ await c.iam.unassignServiceAccountRole('sa1', 'r1');
699
+ strict_1.default.equal(last().path, '/v1/service-accounts/sa1/roles/r1');
700
+ await c.iam.serviceAccountRoles('sa1');
701
+ strict_1.default.equal(last().method, 'GET');
702
+ }
703
+ finally {
704
+ await new Promise((resolve) => server.close(() => resolve()));
705
+ }
706
+ });
707
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synapseone/sdk",
3
- "version": "0.9.0-dev.77",
3
+ "version": "0.9.0-dev.79",
4
4
  "license": "Apache-2.0",
5
5
  "description": "synapseone SDK for JavaScript/TypeScript",
6
6
  "homepage": "https://synapseone.space",