@oxyhq/core 17.0.2 → 17.1.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 (36) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/i18n/locales/en-US.json +6 -0
  3. package/dist/cjs/i18n/locales/es-ES.json +6 -0
  4. package/dist/cjs/i18n/locales/locales/en-US.json +6 -0
  5. package/dist/cjs/i18n/locales/locales/es-ES.json +6 -0
  6. package/dist/cjs/mixins/OxyServices.accounts.js +39 -1
  7. package/dist/cjs/session/accountDialogController.js +3 -1
  8. package/dist/cjs/session/accountProjection.js +19 -1
  9. package/dist/esm/.tsbuildinfo +1 -1
  10. package/dist/esm/i18n/locales/en-US.json +6 -0
  11. package/dist/esm/i18n/locales/es-ES.json +6 -0
  12. package/dist/esm/i18n/locales/locales/en-US.json +6 -0
  13. package/dist/esm/i18n/locales/locales/es-ES.json +6 -0
  14. package/dist/esm/mixins/OxyServices.accounts.js +37 -1
  15. package/dist/esm/session/accountDialogController.js +3 -1
  16. package/dist/esm/session/accountProjection.js +19 -1
  17. package/dist/types/.tsbuildinfo +1 -1
  18. package/dist/types/crypto/keyManager.d.ts +2 -2
  19. package/dist/types/index.d.ts +1 -1
  20. package/dist/types/mixins/OxyServices.accounts.d.ts +73 -9
  21. package/dist/types/models/interfaces.d.ts +17 -1
  22. package/dist/types/session/accountDialogController.d.ts +1 -1
  23. package/dist/types/session/accountProjection.d.ts +6 -0
  24. package/package.json +3 -3
  25. package/src/crypto/keyManager.ts +1 -2
  26. package/src/i18n/locales/en-US.json +6 -0
  27. package/src/i18n/locales/es-ES.json +6 -0
  28. package/src/index.ts +4 -0
  29. package/src/mixins/OxyServices.accounts.ts +115 -12
  30. package/src/models/interfaces.ts +17 -0
  31. package/src/session/__tests__/accountDialogController.test.ts +13 -1
  32. package/src/session/__tests__/accountProjection.test.ts +31 -0
  33. package/src/session/accountDialogController.ts +4 -2
  34. package/src/session/accountProjection.ts +19 -1
  35. package/src/types/color.d.ts +0 -20
  36. package/src/types/elliptic.d.ts +0 -70
@@ -54,6 +54,12 @@
54
54
  "status": {
55
55
  "accountSwitched": "Now using {{name}}",
56
56
  "signingIn": "Signing in…"
57
+ },
58
+ "errors": {
59
+ "notConfigured": "Sign-in isn't available",
60
+ "notConfiguredDescription": "{{app}} isn't set up for sign-in yet. Contact the app's developer.",
61
+ "failed": "Couldn't start sign-in",
62
+ "failedDescription": "Something went wrong. Please try again."
57
63
  }
58
64
  },
59
65
  "signup": {
@@ -54,6 +54,12 @@
54
54
  "status": {
55
55
  "accountSwitched": "Ahora usando {{name}}",
56
56
  "signingIn": "Iniciando sesión…"
57
+ },
58
+ "errors": {
59
+ "notConfigured": "El inicio de sesión no está disponible",
60
+ "notConfiguredDescription": "{{app}} todavía no está configurada para iniciar sesión. Contacta con quien desarrolla la app.",
61
+ "failed": "No se pudo iniciar sesión",
62
+ "failedDescription": "Algo ha ido mal. Inténtalo de nuevo."
57
63
  }
58
64
  },
59
65
  "signup": {
@@ -54,6 +54,12 @@
54
54
  "status": {
55
55
  "accountSwitched": "Now using {{name}}",
56
56
  "signingIn": "Signing in…"
57
+ },
58
+ "errors": {
59
+ "notConfigured": "Sign-in isn't available",
60
+ "notConfiguredDescription": "{{app}} isn't set up for sign-in yet. Contact the app's developer.",
61
+ "failed": "Couldn't start sign-in",
62
+ "failedDescription": "Something went wrong. Please try again."
57
63
  }
58
64
  },
59
65
  "signup": {
@@ -54,6 +54,12 @@
54
54
  "status": {
55
55
  "accountSwitched": "Ahora usando {{name}}",
56
56
  "signingIn": "Iniciando sesión…"
57
+ },
58
+ "errors": {
59
+ "notConfigured": "El inicio de sesión no está disponible",
60
+ "notConfiguredDescription": "{{app}} todavía no está configurada para iniciar sesión. Contacta con quien desarrolla la app.",
61
+ "failed": "No se pudo iniciar sesión",
62
+ "failedDescription": "Algo ha ido mal. Inténtalo de nuevo."
57
63
  }
58
64
  },
59
65
  "signup": {
@@ -1,6 +1,6 @@
1
1
  import { normalizeUserIdentity } from '../utils/userIdentity.js';
2
2
  import { CACHE_TIMES } from './mixinHelpers.js';
3
- export { ORGANIZATION_CATEGORIES } from '@oxyhq/contracts';
3
+ export { ACCOUNT_KINDS, ORGANIZATION_CATEGORIES, isActAsEligibleKind } from '@oxyhq/contracts';
4
4
  export function OxyServicesAccountsMixin(Base) {
5
5
  return class extends Base {
6
6
  constructor(...args) {
@@ -119,6 +119,42 @@ export function OxyServicesAccountsMixin(Base) {
119
119
  throw this.handleError(error);
120
120
  }
121
121
  }
122
+ /**
123
+ * Mint a `channel` account under `ownerUserId` via service auth
124
+ * (`accounts:provision` scope). Requires `configureServiceAuth` first.
125
+ */
126
+ async provisionChannelAccount(data) {
127
+ try {
128
+ return await this.makeServiceRequest('POST', '/accounts/service/channels', data);
129
+ }
130
+ catch (error) {
131
+ throw this.handleError(error);
132
+ }
133
+ }
134
+ /**
135
+ * Grant membership on a channel account via service auth
136
+ * (`accounts:provision` scope).
137
+ */
138
+ async provisionChannelMember(channelAccountId, data) {
139
+ try {
140
+ return await this.makeServiceRequest('POST', `/accounts/service/channels/${encodeURIComponent(channelAccountId)}/members`, data);
141
+ }
142
+ catch (error) {
143
+ throw this.handleError(error);
144
+ }
145
+ }
146
+ /**
147
+ * Revoke membership on a channel account via service auth
148
+ * (`accounts:provision` scope).
149
+ */
150
+ async revokeChannelMember(channelAccountId, memberUserId) {
151
+ try {
152
+ return await this.makeServiceRequest('DELETE', `/accounts/service/channels/${encodeURIComponent(channelAccountId)}/members/${encodeURIComponent(memberUserId)}`);
153
+ }
154
+ catch (error) {
155
+ throw this.handleError(error);
156
+ }
157
+ }
122
158
  /**
123
159
  * Update an account's mutable profile fields. Tree placement changes
124
160
  * (reparenting) go through the dedicated move endpoint, not here.
@@ -455,7 +455,7 @@ export class AccountDialogController {
455
455
  */
456
456
  async switchTo(accountId) {
457
457
  if (this.switchingAccountId)
458
- return;
458
+ return false;
459
459
  this.switchingAccountId = accountId;
460
460
  this.error = null;
461
461
  this.emit();
@@ -484,9 +484,11 @@ export class AccountDialogController {
484
484
  }
485
485
  // Re-project + refetch immediately; the subscription also fires.
486
486
  await this.refresh();
487
+ return true;
487
488
  }
488
489
  catch (error) {
489
490
  this.error = errorMessage(error);
491
+ return false;
490
492
  }
491
493
  finally {
492
494
  this.switchingAccountId = null;
@@ -16,6 +16,7 @@
16
16
  * into core, keyed directly on `DeviceSessionState` (whose `activeAccountId` is
17
17
  * atomic, so no cross-call current-row reconciliation is needed).
18
18
  */
19
+ import { isActAsEligibleKind } from '@oxyhq/contracts';
19
20
  import { getAccountDisplayName, getAccountFallbackHandle } from '../utils/accountUtils.js';
20
21
  import { getNormalizedUserHandle } from '../utils/userHandle.js';
21
22
  /**
@@ -26,6 +27,9 @@ import { getNormalizedUserHandle } from '../utils/userHandle.js';
26
27
  * graph-only rows (in graph order). An account present as BOTH a device session
27
28
  * and a graph node is deduped into ONE device row enriched with the graph
28
29
  * metadata (relationship / kind / parent / membership).
30
+ *
31
+ * Graph nodes of a kind nobody may act as (`channel`) are omitted — see the
32
+ * filter below.
29
33
  */
30
34
  export function projectSwitchableAccounts(input) {
31
35
  const { state, graph, profilesById, activeUser, locale, resolveAvatarUrl } = input;
@@ -95,6 +99,17 @@ export function projectSwitchableAccounts(input) {
95
99
  continue;
96
100
  }
97
101
  // Graph-only account (owned org / shared, not yet a device session).
102
+ //
103
+ // This lane is why a no-login account is NOT kept out of the switcher "by
104
+ // construction": the graph contributes accounts that have no device session
105
+ // and no credentials at all, which is exactly how an org first becomes
106
+ // switchable. So a kind that must never be switched into has to be filtered
107
+ // HERE, and `isActAsEligibleKind` is the same predicate the server enforces
108
+ // on `POST /accounts/:id/switch` — offering a row the server would 403 is a
109
+ // dead button.
110
+ if (!isActAsEligibleKind(node.kind)) {
111
+ continue;
112
+ }
98
113
  remember(toRow(node.account, {
99
114
  relationship: node.relationship,
100
115
  kind: node.kind,
@@ -113,6 +128,9 @@ export function projectSwitchableAccounts(input) {
113
128
  * `oxyServices.getUsersByIds(...)`; graph nodes already embed their `account`
114
129
  * document, but including their ids lets the caller pass one id set and lets the
115
130
  * projection prefer freshly-fetched profiles uniformly.
131
+ *
132
+ * Applies the SAME act-as filter as {@link projectSwitchableAccounts} to graph
133
+ * nodes, so this never fetches a profile for a row the projection will drop.
116
134
  */
117
135
  export function switchableAccountIds(state, graph) {
118
136
  const ids = new Set();
@@ -122,7 +140,7 @@ export function switchableAccountIds(state, graph) {
122
140
  }
123
141
  }
124
142
  for (const node of graph) {
125
- if (node.accountId) {
143
+ if (node.accountId && isActAsEligibleKind(node.kind)) {
126
144
  ids.add(node.accountId);
127
145
  }
128
146
  }