@oxy.so/core 7.23.1 → 7.24.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.
@@ -1,6 +1,39 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AccountsApi = exports.AccountInvitationsApi = exports.AccountAgentKeysApi = exports.AccountMembersApi = exports.kindAcceptsAccountCategories = exports.isSelectableAccountCategoryId = exports.isOperatorSwitchTargetKind = exports.isDelegatedActAsEligibleKind = exports.SELECTABLE_ACCOUNT_CATEGORY_IDS = exports.MAX_ACCOUNT_CATEGORIES = exports.ACCOUNT_KINDS = exports.ACCOUNT_CATEGORY_IDS = void 0;
36
+ exports.AccountsApi = exports.AccountInvitationsApi = exports.AccountIdentityKeyApi = exports.AccountAgentKeysApi = exports.AccountMembersApi = exports.kindAcceptsAccountCategories = exports.isSelectableAccountCategoryId = exports.isOperatorSwitchTargetKind = exports.isDelegatedActAsEligibleKind = exports.SELECTABLE_ACCOUNT_CATEGORY_IDS = exports.MAX_ACCOUNT_CATEGORIES = exports.ACCOUNT_KINDS = exports.ACCOUNT_CATEGORY_IDS = void 0;
4
37
  const client_1 = require("@oxy.so/contracts/client");
5
38
  const userIdentity_1 = require("../utils/userIdentity");
6
39
  const identityCacheSweep_1 = require("../utils/identityCacheSweep");
@@ -88,6 +121,73 @@ class AccountAgentKeysApi {
88
121
  }
89
122
  }
90
123
  exports.AccountAgentKeysApi = AccountAgentKeysApi;
124
+ /**
125
+ * `oxy.accounts.identityKey` — an organization's identity key (ADR 0061): its
126
+ * DID `#key-1`, the key Peable derives its FairCoin receive addresses from.
127
+ * Only the organization's owners and admins may read or change it; the key is
128
+ * created and held in Commons and never signs anybody in.
129
+ *
130
+ * `get` answers `publicKey: null` for an organization that has no key yet (its
131
+ * DID lists no `#key-1`): that is when a client shows its owners "Set up the
132
+ * organization's Peable wallet". A 403 (`ORGANIZATION_KEY_FORBIDDEN`) means the
133
+ * signed-in person is not an owner or admin of a claimed, active organization.
134
+ */
135
+ class AccountIdentityKeyApi {
136
+ constructor(ctx) {
137
+ this.ctx = ctx;
138
+ }
139
+ /** The organization's key (`null` without one) and every key it has had, oldest first. */
140
+ async get(accountId) {
141
+ return (0, client_1.parseContract)(client_1.organizationIdentityKeyStateCheck, await this.ctx.request('GET', `/accounts/${enc(accountId)}/identity-key`, undefined, { cache: false }));
142
+ }
143
+ /** A one-use challenge for one change, with the claims every signer signs. */
144
+ async requestChallenge(accountId, request) {
145
+ return (0, client_1.parseContract)(client_1.organizationKeyChallengeCheck, await this.ctx.request('POST', `/accounts/${enc(accountId)}/identity-key/challenge`, (0, client_1.parseContract)(client_1.organizationKeyChallengeRequestCheck, request), { cache: false }));
146
+ }
147
+ /** Apply a change with its signatures (see {@link link} for the whole ceremony). */
148
+ async apply(accountId, request) {
149
+ return (0, client_1.parseContract)(client_1.organizationIdentityKeyStateCheck, await this.ctx.request('POST', `/accounts/${enc(accountId)}/identity-key`, (0, client_1.parseContract)(client_1.organizationKeyApplyRequestCheck, request), { cache: false }));
150
+ }
151
+ /**
152
+ * Commons' whole ceremony. NATIVE-ONLY: the actor is THIS device's personal
153
+ * root (`KeyManager`), which must be the signed-in person's. `key` is the
154
+ * organization key the device generated (`create`, or `replace` with a new
155
+ * one); `previousKey` is the current organization key when the device holds
156
+ * it, so the replacement is recorded as proven by it.
157
+ */
158
+ async link(accountId, input) {
159
+ const { KeyManager, signIdentityProof } = await Promise.resolve().then(() => __importStar(require('../crypto/index')));
160
+ const [rootPrivateKey, rootPublicKey] = await Promise.all([
161
+ KeyManager.getPrivateKey(),
162
+ KeyManager.getPublicKey(),
163
+ ]);
164
+ if (!rootPrivateKey || !rootPublicKey) {
165
+ throw new Error('No identity on this device to sign with');
166
+ }
167
+ const challenge = await this.requestChallenge(accountId, {
168
+ operation: input.operation,
169
+ publicKey: input.key.publicKey,
170
+ });
171
+ const root = rootPublicKey.trim().toLowerCase();
172
+ if (challenge.actorPublicKey !== root) {
173
+ throw new Error("This device's identity is not the signed-in account's");
174
+ }
175
+ const sign = async (signer, publicKey) => (await signIdentityProof({ privateKey: signer.privateKey, publicKey }, (0, client_1.organizationKeyProofClaims)(challenge, publicKey))).signature;
176
+ const previousPublicKey = challenge.previousPublicKey;
177
+ return this.apply(accountId, {
178
+ operation: input.operation,
179
+ publicKey: challenge.publicKey,
180
+ challenge: challenge.challenge,
181
+ expiresAt: challenge.expiresAt,
182
+ actorSignature: await sign({ privateKey: rootPrivateKey, publicKey: root }, root),
183
+ keySignature: await sign(input.key, challenge.publicKey),
184
+ ...(input.previousKey && previousPublicKey
185
+ ? { previousKeySignature: await sign(input.previousKey, previousPublicKey) }
186
+ : {}),
187
+ });
188
+ }
189
+ }
190
+ exports.AccountIdentityKeyApi = AccountIdentityKeyApi;
91
191
  /** Consent-based invitations; never cached or queued as offline mutations. */
92
192
  class AccountInvitationsApi {
93
193
  constructor(ctx) {
@@ -123,6 +223,7 @@ class AccountsApi {
123
223
  this.members = new AccountMembersApi(ctx);
124
224
  this.invitations = new AccountInvitationsApi(ctx);
125
225
  this.agentKeys = new AccountAgentKeysApi(ctx);
226
+ this.identityKey = new AccountIdentityKeyApi(ctx);
126
227
  }
127
228
  /**
128
229
  * List the accounts the caller can access: their own personal (root)
@@ -6,7 +6,7 @@
6
6
  * `oxy.store` says what the store lists; an installer says what the machine can do with a
7
7
  * listing. A runtime that installs applications registers one (OxyOS's Bloom host registers one
8
8
  * backed by the system's install service before the application's code runs, OxyOS ADR 0030
9
- * decision 9; ADR 0053 here). Where none is registered — the web, iOS, Android — there is
9
+ * decision 9; ADR 0059 here). Where none is registered — the web, iOS, Android — there is
10
10
  * nothing to install, and a store shows what it shows without one. An application never asks
11
11
  * which platform it runs on: it asks whether there is an installer.
12
12
  *