@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.
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/i18n/locales/en-US.json +6 -0
- package/dist/cjs/i18n/locales/es-ES.json +6 -0
- package/dist/cjs/i18n/locales/locales/en-US.json +6 -0
- package/dist/cjs/i18n/locales/locales/es-ES.json +6 -0
- package/dist/cjs/mixins/OxyServices.accounts.js +39 -1
- package/dist/cjs/session/accountDialogController.js +3 -1
- package/dist/cjs/session/accountProjection.js +19 -1
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/i18n/locales/en-US.json +6 -0
- package/dist/esm/i18n/locales/es-ES.json +6 -0
- package/dist/esm/i18n/locales/locales/en-US.json +6 -0
- package/dist/esm/i18n/locales/locales/es-ES.json +6 -0
- package/dist/esm/mixins/OxyServices.accounts.js +37 -1
- package/dist/esm/session/accountDialogController.js +3 -1
- package/dist/esm/session/accountProjection.js +19 -1
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/crypto/keyManager.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/mixins/OxyServices.accounts.d.ts +73 -9
- package/dist/types/models/interfaces.d.ts +17 -1
- package/dist/types/session/accountDialogController.d.ts +1 -1
- package/dist/types/session/accountProjection.d.ts +6 -0
- package/package.json +3 -3
- package/src/crypto/keyManager.ts +1 -2
- package/src/i18n/locales/en-US.json +6 -0
- package/src/i18n/locales/es-ES.json +6 -0
- package/src/index.ts +4 -0
- package/src/mixins/OxyServices.accounts.ts +115 -12
- package/src/models/interfaces.ts +17 -0
- package/src/session/__tests__/accountDialogController.test.ts +13 -1
- package/src/session/__tests__/accountProjection.test.ts +31 -0
- package/src/session/accountDialogController.ts +4 -2
- package/src/session/accountProjection.ts +19 -1
- package/src/types/color.d.ts +0 -20
- 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
|
}
|