stellarium-ts 0.12.0 → 0.13.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.
Files changed (77) hide show
  1. package/dist/client/operatorClient.d.ts +10 -4
  2. package/dist/client/operatorClient.d.ts.map +1 -1
  3. package/dist/client/operatorClient.js +51 -7
  4. package/dist/crypto/utils.d.ts +9 -0
  5. package/dist/crypto/utils.d.ts.map +1 -1
  6. package/dist/crypto/utils.js +30 -1
  7. package/dist/db/db.d.ts +5 -4
  8. package/dist/db/db.d.ts.map +1 -1
  9. package/dist/db/db.js +88 -12
  10. package/dist/grant/grant.d.ts +132 -0
  11. package/dist/grant/grant.d.ts.map +1 -0
  12. package/dist/grant/grant.js +158 -0
  13. package/dist/grant/repository.d.ts +57 -0
  14. package/dist/grant/repository.d.ts.map +1 -0
  15. package/dist/grant/repository.js +105 -0
  16. package/dist/grant/service.d.ts +141 -0
  17. package/dist/grant/service.d.ts.map +1 -0
  18. package/dist/grant/service.js +431 -0
  19. package/dist/index.d.ts +6 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +5 -1
  22. package/dist/peer/repository.d.ts +33 -2
  23. package/dist/peer/repository.d.ts.map +1 -1
  24. package/dist/peer/repository.js +43 -21
  25. package/dist/resource/invoker.d.ts +21 -9
  26. package/dist/resource/invoker.d.ts.map +1 -1
  27. package/dist/resource/invoker.js +69 -16
  28. package/dist/resource/repository.d.ts +47 -8
  29. package/dist/resource/repository.d.ts.map +1 -1
  30. package/dist/resource/repository.js +122 -67
  31. package/dist/routes.d.ts +8 -0
  32. package/dist/routes.d.ts.map +1 -1
  33. package/dist/routes.js +302 -48
  34. package/dist/server.d.ts +62 -0
  35. package/dist/server.d.ts.map +1 -1
  36. package/dist/server.js +119 -18
  37. package/dist/service.d.ts +24 -1
  38. package/dist/service.d.ts.map +1 -1
  39. package/dist/service.js +9 -6
  40. package/dist/startup.d.ts +14 -0
  41. package/dist/startup.d.ts.map +1 -1
  42. package/dist/startup.js +90 -76
  43. package/dist/tests/client/operatorClient.test.d.ts +2 -0
  44. package/dist/tests/client/operatorClient.test.d.ts.map +1 -0
  45. package/dist/tests/client/operatorClient.test.js +96 -0
  46. package/dist/tests/db/db.test.d.ts +2 -0
  47. package/dist/tests/db/db.test.d.ts.map +1 -0
  48. package/dist/tests/db/db.test.js +64 -0
  49. package/dist/tests/grant/grant.test.d.ts +2 -0
  50. package/dist/tests/grant/grant.test.d.ts.map +1 -0
  51. package/dist/tests/grant/grant.test.js +133 -0
  52. package/dist/tests/grant/service.test.d.ts +2 -0
  53. package/dist/tests/grant/service.test.d.ts.map +1 -0
  54. package/dist/tests/grant/service.test.js +415 -0
  55. package/dist/tests/helpers.d.ts +13 -0
  56. package/dist/tests/helpers.d.ts.map +1 -0
  57. package/dist/tests/helpers.js +49 -0
  58. package/dist/tests/integration/network.test.d.ts +2 -0
  59. package/dist/tests/integration/network.test.d.ts.map +1 -0
  60. package/dist/tests/integration/network.test.js +188 -0
  61. package/dist/tests/peer/repository.test.d.ts +2 -0
  62. package/dist/tests/peer/repository.test.d.ts.map +1 -0
  63. package/dist/tests/peer/repository.test.js +50 -0
  64. package/dist/tests/resource/invoker.test.js +132 -5
  65. package/dist/tests/resource/repository.test.d.ts +2 -0
  66. package/dist/tests/resource/repository.test.d.ts.map +1 -0
  67. package/dist/tests/resource/repository.test.js +151 -0
  68. package/dist/tests/routes.test.d.ts +2 -0
  69. package/dist/tests/routes.test.d.ts.map +1 -0
  70. package/dist/tests/routes.test.js +565 -0
  71. package/dist/tests/server.test.d.ts +2 -0
  72. package/dist/tests/server.test.d.ts.map +1 -0
  73. package/dist/tests/server.test.js +37 -0
  74. package/dist/tests/startup.test.d.ts +2 -0
  75. package/dist/tests/startup.test.d.ts.map +1 -0
  76. package/dist/tests/startup.test.js +75 -0
  77. package/package.json +2 -1
@@ -0,0 +1,57 @@
1
+ import type { Database } from "sqlite";
2
+ import type { Capability, Grant } from "./grant.js";
3
+ export interface IssuedGrant {
4
+ id: string;
5
+ audience: string;
6
+ capabilities: Capability[];
7
+ /** The held grant this one was delegated from, or null for a root grant. */
8
+ parent: GrantKey | null;
9
+ lifetimeMs: number;
10
+ renewableUntil: string | null;
11
+ }
12
+ export interface BlockedCaller {
13
+ publicKey: string;
14
+ reason: string | null;
15
+ blockedAt: string;
16
+ }
17
+ /**
18
+ * Identifies a grant, such as a held chain's leaf or a revoked grant. Issuers choose their own
19
+ * ids, so the id alone isn't enough.
20
+ */
21
+ export interface GrantKey {
22
+ issuer: string;
23
+ id: string;
24
+ }
25
+ /** Grants this node issued, grants it holds, grants it revoked, nonces it has seen, and caller keys it blocked. */
26
+ export declare class GrantRepository {
27
+ private readonly db;
28
+ constructor(db: Database);
29
+ saveIssued(grant: IssuedGrant): Promise<void>;
30
+ getIssued(id: string): Promise<IssuedGrant | undefined>;
31
+ /** Saves a chain this node holds, replacing an earlier copy of the same leaf grant. */
32
+ saveHeld(chain: Grant[]): Promise<void>;
33
+ getHeld(key: GrantKey): Promise<Grant[] | undefined>;
34
+ /** Every held chain whose leaf has this id, whoever issued it. */
35
+ getHeldById(id: string): Promise<Grant[][]>;
36
+ deleteHeld(key: GrantKey): Promise<void>;
37
+ /** Unexpired chains rooted at the node serving `rootIssuerBaseUrl`, latest expiry first. */
38
+ getUnexpiredHeldByRoot(rootIssuerBaseUrl: string, now: number): Promise<Grant[][]>;
39
+ /** Expired chains rooted at the node serving `rootIssuerBaseUrl`, latest expiry first. */
40
+ getExpiredHeldByRoot(rootIssuerBaseUrl: string, now: number): Promise<Grant[][]>;
41
+ getAllHeld(): Promise<Grant[][]>;
42
+ /** The key of the peer serving `baseUrl`, if this node knows it. */
43
+ getPeerKey(baseUrl: string): Promise<string | undefined>;
44
+ revoke(key: GrantKey): Promise<void>;
45
+ anyRevoked(keys: GrantKey[]): Promise<boolean>;
46
+ /** False when `key` was already claimed. */
47
+ claimNonce(key: string, expiresAt: number): Promise<boolean>;
48
+ deleteExpiredNonces(now: number): Promise<void>;
49
+ /** Blocking a blocked key again updates its reason and keeps the original time. */
50
+ block(publicKey: string, reason: string | null): Promise<void>;
51
+ /** False when the key wasn't blocked. */
52
+ unblock(publicKey: string): Promise<boolean>;
53
+ anyBlocked(publicKeys: string[]): Promise<boolean>;
54
+ /** In the order they were blocked. */
55
+ getBlocked(offset: number, limit: number): Promise<BlockedCaller[]>;
56
+ }
57
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/grant/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /** Stored times are normalized so that SQL can order and compare them as text. */
2
+ const isoTime = (time) => new Date(typeof time === 'string' ? Date.parse(time) : time).toISOString();
3
+ /** Grants this node issued, grants it holds, grants it revoked, nonces it has seen, and caller keys it blocked. */
4
+ export class GrantRepository {
5
+ db;
6
+ constructor(db) {
7
+ this.db = db;
8
+ }
9
+ async saveIssued(grant) {
10
+ await this.db.run('INSERT INTO issued_grant (id, audience, capabilities, parent_grant_issuer, parent_grant_id, lifetime_ms, renewable_until, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', [grant.id, grant.audience, JSON.stringify(grant.capabilities), grant.parent?.issuer ?? null, grant.parent?.id ?? null, grant.lifetimeMs, grant.renewableUntil, new Date().toISOString()]);
11
+ }
12
+ async getIssued(id) {
13
+ const row = await this.db.get('SELECT * FROM issued_grant WHERE id = ?', [id]);
14
+ if (!row) {
15
+ return undefined;
16
+ }
17
+ return {
18
+ id: row.id,
19
+ audience: row.audience,
20
+ capabilities: JSON.parse(row.capabilities),
21
+ parent: row.parent_grant_issuer !== null && row.parent_grant_id !== null ? { issuer: row.parent_grant_issuer, id: row.parent_grant_id } : null,
22
+ lifetimeMs: row.lifetime_ms,
23
+ renewableUntil: row.renewable_until,
24
+ };
25
+ }
26
+ /** Saves a chain this node holds, replacing an earlier copy of the same leaf grant. */
27
+ async saveHeld(chain) {
28
+ const leaf = chain[chain.length - 1];
29
+ await this.db.run(`INSERT INTO held_grant (issuer, id, root_issuer_base_url, chain, issued_at, expires_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)
30
+ ON CONFLICT (issuer, id) DO UPDATE SET root_issuer_base_url = excluded.root_issuer_base_url, chain = excluded.chain,
31
+ issued_at = excluded.issued_at, expires_at = excluded.expires_at, updated_at = excluded.updated_at`, [leaf.issuer, leaf.id, chain[0].issuerBaseUrl, JSON.stringify(chain), isoTime(leaf.issuedAt), isoTime(leaf.expiresAt), new Date().toISOString()]);
32
+ }
33
+ async getHeld(key) {
34
+ const row = await this.db.get('SELECT chain FROM held_grant WHERE issuer = ? AND id = ?', [key.issuer, key.id]);
35
+ return row ? JSON.parse(row.chain) : undefined;
36
+ }
37
+ /** Every held chain whose leaf has this id, whoever issued it. */
38
+ async getHeldById(id) {
39
+ const rows = await this.db.all('SELECT chain FROM held_grant WHERE id = ? ORDER BY issuer', [id]);
40
+ return rows.map(row => JSON.parse(row.chain));
41
+ }
42
+ async deleteHeld(key) {
43
+ await this.db.run('DELETE FROM held_grant WHERE issuer = ? AND id = ?', [key.issuer, key.id]);
44
+ }
45
+ /** Unexpired chains rooted at the node serving `rootIssuerBaseUrl`, latest expiry first. */
46
+ async getUnexpiredHeldByRoot(rootIssuerBaseUrl, now) {
47
+ const rows = await this.db.all('SELECT chain FROM held_grant WHERE root_issuer_base_url = ? AND expires_at > ? ORDER BY expires_at DESC', [rootIssuerBaseUrl, isoTime(now)]);
48
+ return rows.map(row => JSON.parse(row.chain));
49
+ }
50
+ /** Expired chains rooted at the node serving `rootIssuerBaseUrl`, latest expiry first. */
51
+ async getExpiredHeldByRoot(rootIssuerBaseUrl, now) {
52
+ const rows = await this.db.all('SELECT chain FROM held_grant WHERE root_issuer_base_url = ? AND expires_at <= ? ORDER BY expires_at DESC', [rootIssuerBaseUrl, isoTime(now)]);
53
+ return rows.map(row => JSON.parse(row.chain));
54
+ }
55
+ async getAllHeld() {
56
+ const rows = await this.db.all('SELECT chain FROM held_grant ORDER BY issuer, id');
57
+ return rows.map(row => JSON.parse(row.chain));
58
+ }
59
+ /** The key of the peer serving `baseUrl`, if this node knows it. */
60
+ async getPeerKey(baseUrl) {
61
+ const row = await this.db.get('SELECT public_key FROM peer WHERE base_url = ?', [baseUrl]);
62
+ return row?.public_key;
63
+ }
64
+ async revoke(key) {
65
+ await this.db.run('INSERT INTO revoked_grant (issuer, grant_id, revoked_at) VALUES (?, ?, ?) ON CONFLICT (issuer, grant_id) DO NOTHING', [key.issuer, key.id, new Date().toISOString()]);
66
+ }
67
+ async anyRevoked(keys) {
68
+ if (keys.length === 0) {
69
+ return false;
70
+ }
71
+ const conditions = keys.map(() => '(issuer = ? AND grant_id = ?)').join(' OR ');
72
+ const row = await this.db.get(`SELECT 1 FROM revoked_grant WHERE ${conditions} LIMIT 1`, keys.flatMap(key => [key.issuer, key.id]));
73
+ return row !== undefined;
74
+ }
75
+ /** False when `key` was already claimed. */
76
+ async claimNonce(key, expiresAt) {
77
+ const result = await this.db.run('INSERT INTO seen_nonce (key, expires_at) VALUES (?, ?) ON CONFLICT (key) DO NOTHING', [key, expiresAt]);
78
+ return (result.changes ?? 0) > 0;
79
+ }
80
+ async deleteExpiredNonces(now) {
81
+ await this.db.run('DELETE FROM seen_nonce WHERE expires_at <= ?', [now]);
82
+ }
83
+ /** Blocking a blocked key again updates its reason and keeps the original time. */
84
+ async block(publicKey, reason) {
85
+ await this.db.run('INSERT INTO blocked_caller (public_key, reason, blocked_at) VALUES (?, ?, ?) ON CONFLICT (public_key) DO UPDATE SET reason = excluded.reason', [publicKey, reason, new Date().toISOString()]);
86
+ }
87
+ /** False when the key wasn't blocked. */
88
+ async unblock(publicKey) {
89
+ const result = await this.db.run('DELETE FROM blocked_caller WHERE public_key = ?', [publicKey]);
90
+ return (result.changes ?? 0) > 0;
91
+ }
92
+ async anyBlocked(publicKeys) {
93
+ if (publicKeys.length === 0) {
94
+ return false;
95
+ }
96
+ const placeholders = publicKeys.map(() => '?').join(', ');
97
+ const row = await this.db.get(`SELECT 1 FROM blocked_caller WHERE public_key IN (${placeholders}) LIMIT 1`, publicKeys);
98
+ return row !== undefined;
99
+ }
100
+ /** In the order they were blocked. */
101
+ async getBlocked(offset, limit) {
102
+ const rows = await this.db.all('SELECT * FROM blocked_caller ORDER BY blocked_at, public_key LIMIT ? OFFSET ?', [limit, offset]);
103
+ return rows.map(row => ({ publicKey: row.public_key, reason: row.reason, blockedAt: row.blocked_at }));
104
+ }
105
+ }
@@ -0,0 +1,141 @@
1
+ import type { ResourceFunctionCallParameter } from "requestscript";
2
+ import type { NodeConfig } from "../service.js";
3
+ import { type Capability, type Grant, type GrantRenewalRequest, type GrantRequest, type InvocationAuthorization } from "./grant.js";
4
+ import type { BlockedCaller, GrantRepository, GrantKey } from "./repository.js";
5
+ export interface GrantOptions {
6
+ /** How long each issued copy lasts. At most `MAX_GRANT_LIFETIME_MS`. */
7
+ lifetimeMs: number;
8
+ /** Access ends at this time: no copy expires later, and none is renewed after it. Omit to allow renewal until revoked. */
9
+ renewableUntil?: string;
10
+ }
11
+ /** What an approval hook decides: how long the grant lasts, and optionally narrower capabilities than requested. */
12
+ export interface GrantApproval extends GrantOptions {
13
+ capabilities?: Capability[];
14
+ }
15
+ /**
16
+ * Decides a signed grant request. The caller's key and the request's freshness are already
17
+ * checked. Return undefined to refuse.
18
+ */
19
+ export type ApproveGrant = (request: {
20
+ publicKey: string;
21
+ capabilities: Capability[];
22
+ details: Record<string, unknown> | null;
23
+ }) => GrantApproval | undefined | Promise<GrantApproval | undefined>;
24
+ export interface InvocationTarget {
25
+ resourcePath: string;
26
+ resourceName: string;
27
+ functionName: string;
28
+ parameters: ResourceFunctionCallParameter[];
29
+ }
30
+ export interface RefreshResult {
31
+ renewed: string[];
32
+ failed: {
33
+ id: string;
34
+ error: string;
35
+ }[];
36
+ /** Chains expired for longer than `HELD_GRANT_RETENTION_MS` whose issuer still refused renewal. They are deleted. */
37
+ removed: string[];
38
+ }
39
+ /** Per grant request or renewal. */
40
+ export declare const GRANT_RENEW_TIMEOUT_MS = 10000;
41
+ /**
42
+ * How long a held chain is kept after it expires while its issuer refuses to renew it. A refusal
43
+ * may be temporary, such as while this node's key is blocked, so chains aren't deleted at once.
44
+ */
45
+ export declare const HELD_GRANT_RETENTION_MS: number;
46
+ /** Thrown by `block` for a key that isn't an Ed25519 SPKI key. */
47
+ export declare class InvalidPublicKeyError extends Error {
48
+ constructor();
49
+ }
50
+ /**
51
+ * Issues, holds, renews and verifies capability grants. Every node plays all three roles:
52
+ * a provider issues root grants, a holder can delegate narrower grants and renew them for
53
+ * its own audiences, and renewal of either kind goes through `renew`.
54
+ */
55
+ export declare class GrantService {
56
+ private readonly repository;
57
+ private readonly config;
58
+ private readonly approveGrant?;
59
+ private lastNonceSweep;
60
+ /** Without `approveGrant`, this node refuses every grant request. */
61
+ constructor(repository: GrantRepository, config: Pick<NodeConfig, "baseUrl" | "publicKey" | "privateKey">, approveGrant?: ApproveGrant | undefined);
62
+ get acceptsRequests(): boolean;
63
+ /** Issues a root grant for this node's resources. Returns it as a one-grant chain. */
64
+ issue(audience: string, capabilities: Capability[], options: GrantOptions): Promise<Grant[]>;
65
+ /**
66
+ * Narrows a grant this node holds for another audience. The child expires no later than the
67
+ * held grant. Name the held grant by its id, or by its issuer and id when two issuers used the same id.
68
+ */
69
+ delegate(heldGrant: string | GrantKey, audience: string, capabilities: Capability[], options: GrantOptions): Promise<Grant[]>;
70
+ /**
71
+ * Revoked grants are refused in any chain this node verifies, and are never renewed. A
72
+ * delegator's revocation only stops renewal, since the provider never sees it, so it
73
+ * takes effect when the current copy expires. Name a grant this node issued by its id, and
74
+ * any other grant, such as one delegated further down a chain, by its issuer and id.
75
+ */
76
+ revoke(grant: string | GrantKey): Promise<void>;
77
+ /**
78
+ * Refuses `publicKey` everywhere this node can identify a caller: in any position of a
79
+ * restricted call's chain, and in renewals, grant requests and payment vouchers.
80
+ */
81
+ block(publicKey: string, reason?: string): Promise<void>;
82
+ /** False when the key wasn't blocked. */
83
+ unblock(publicKey: string): Promise<boolean>;
84
+ isBlocked(publicKey: string): Promise<boolean>;
85
+ getBlocked(offset: number, limit: number): Promise<BlockedCaller[]>;
86
+ /** Handles a holder's renewal request for a grant this node issued. Returns the fresh chain, or undefined if refused. */
87
+ renew(request: GrantRenewalRequest): Promise<Grant[] | undefined>;
88
+ /**
89
+ * Handles a caller's request for a new root grant: checks its signature and nonce, then
90
+ * asks the approval hook. Returns the issued chain, or undefined if refused. Throws if the
91
+ * hook throws or returns an invalid approval; the caller must then sign a new request.
92
+ */
93
+ handleRequest(request: GrantRequest): Promise<Grant[] | undefined>;
94
+ /**
95
+ * Asks the node at `providerBaseUrl` for a root grant and stores it. Throws if refused.
96
+ * The provider verifies the grant again on every call, so a grant from the wrong key only fails there.
97
+ */
98
+ request(providerBaseUrl: string, capabilities: Capability[], details?: Record<string, unknown>): Promise<Grant[]>;
99
+ /** Stores a chain whose leaf names this node as its audience. Throws if the chain is invalid. */
100
+ add(chain: Grant[]): Promise<void>;
101
+ /**
102
+ * Stores a chain passed in the node's start options. A held copy of the same grant that
103
+ * expires no earlier is a renewal of it, so it is kept. Returns false, storing nothing, for
104
+ * an expired chain. Throws if the chain is otherwise invalid.
105
+ */
106
+ seed(chain: Grant[]): Promise<boolean>;
107
+ /**
108
+ * A held chain, rooted at the node serving `rootBaseUrl`, that covers the call. When every
109
+ * such chain has expired, the latest-expiring one is renewed, once, before giving up, so a
110
+ * call waits on at most one renewal. Undefined when this node holds no usable grant.
111
+ */
112
+ chainFor(rootBaseUrl: string, target: InvocationTarget): Promise<Grant[] | undefined>;
113
+ /** Builds the authorization sent with a call. Sign a new one per attempt: providers refuse a reused nonce. */
114
+ authorize(chain: Grant[], target: InvocationTarget): InvocationAuthorization;
115
+ /**
116
+ * Renews every held chain past half its lifetime. A failed renewal keeps the current copy,
117
+ * unless the issuer refused it and the chain expired more than `HELD_GRANT_RETENTION_MS` ago.
118
+ */
119
+ refreshDue(): Promise<RefreshResult>;
120
+ /**
121
+ * True when `authorization` lets its signer make exactly this call: the chain is rooted at
122
+ * this node, unrevoked, addressed to the signer and covers the call, and the nonce is new.
123
+ */
124
+ verifyInvocation(authorization: unknown, target: InvocationTarget): Promise<boolean>;
125
+ /**
126
+ * Nonces are kept in the node's database, so they survive a restart. Replicas of a node that
127
+ * don't share a database don't see each other's nonces.
128
+ */
129
+ private claimNonce;
130
+ private findHeld;
131
+ /** Asks the leaf grant's issuer for a fresh chain and stores it. Throws if refused or invalid. */
132
+ private renewHeld;
133
+ /**
134
+ * POSTs a signed request to another node's grant endpoint and returns the chain it answered
135
+ * with, unverified. Throws `GrantRefusedError` if the node refused, and an Error if it failed.
136
+ */
137
+ private postForGrants;
138
+ /** The copy expires after `lifetimeMs`, but no later than its parent or `renewableUntil`. */
139
+ private sign;
140
+ }
141
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/grant/service.ts"],"names":[],"mappings":"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"}