@oxyhq/core 3.18.1 → 4.0.1
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/OxyServices.js +3 -2
- package/dist/cjs/i18n/locales/en-US.json +391 -17
- package/dist/cjs/i18n/locales/es-ES.json +391 -17
- package/dist/cjs/i18n/locales/locales/en-US.json +391 -17
- package/dist/cjs/i18n/locales/locales/es-ES.json +391 -17
- package/dist/cjs/mixins/OxyServices.accounts.js +480 -0
- package/dist/cjs/mixins/OxyServices.connectedApps.js +73 -0
- package/dist/cjs/mixins/OxyServices.utility.js +3 -2
- package/dist/cjs/mixins/index.js +9 -6
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/OxyServices.js +3 -2
- package/dist/esm/i18n/locales/en-US.json +391 -17
- package/dist/esm/i18n/locales/es-ES.json +391 -17
- package/dist/esm/i18n/locales/locales/en-US.json +391 -17
- package/dist/esm/i18n/locales/locales/es-ES.json +391 -17
- package/dist/esm/mixins/OxyServices.accounts.js +477 -0
- package/dist/esm/mixins/OxyServices.connectedApps.js +70 -0
- package/dist/esm/mixins/OxyServices.utility.js +3 -2
- package/dist/esm/mixins/index.js +9 -6
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/OxyServices.d.ts +3 -2
- package/dist/types/index.d.ts +2 -3
- package/dist/types/mixins/OxyServices.accounts.d.ts +642 -0
- package/dist/types/mixins/OxyServices.auth.d.ts +1 -1
- package/dist/types/mixins/OxyServices.connectedApps.d.ts +168 -0
- package/dist/types/mixins/OxyServices.utility.d.ts +6 -3
- package/dist/types/mixins/index.d.ts +3 -4
- package/package.json +1 -1
- package/src/OxyServices.ts +3 -2
- package/src/i18n/locales/en-US.json +391 -17
- package/src/i18n/locales/es-ES.json +391 -17
- package/src/index.ts +33 -34
- package/src/mixins/OxyServices.accounts.ts +1079 -0
- package/src/mixins/OxyServices.auth.ts +1 -1
- package/src/mixins/OxyServices.connectedApps.ts +165 -0
- package/src/mixins/OxyServices.utility.ts +7 -4
- package/src/mixins/__tests__/accounts.test.ts +667 -0
- package/src/mixins/__tests__/connectedApps.test.ts +1 -1
- package/src/mixins/index.ts +11 -9
- package/dist/cjs/mixins/OxyServices.applications.js +0 -350
- package/dist/cjs/mixins/OxyServices.managedAccounts.js +0 -143
- package/dist/cjs/mixins/OxyServices.workspaces.js +0 -181
- package/dist/esm/mixins/OxyServices.applications.js +0 -347
- package/dist/esm/mixins/OxyServices.managedAccounts.js +0 -140
- package/dist/esm/mixins/OxyServices.workspaces.js +0 -178
- package/dist/types/mixins/OxyServices.applications.d.ts +0 -496
- package/dist/types/mixins/OxyServices.managedAccounts.d.ts +0 -145
- package/dist/types/mixins/OxyServices.workspaces.d.ts +0 -219
- package/src/mixins/OxyServices.applications.ts +0 -773
- package/src/mixins/OxyServices.managedAccounts.ts +0 -173
- package/src/mixins/OxyServices.workspaces.ts +0 -351
package/src/mixins/index.ts
CHANGED
|
@@ -18,8 +18,8 @@ import { OxyServicesLanguageMixin } from './OxyServices.language';
|
|
|
18
18
|
import { OxyServicesPaymentMixin } from './OxyServices.payment';
|
|
19
19
|
import { OxyServicesReputationMixin } from './OxyServices.reputation';
|
|
20
20
|
import { OxyServicesAssetsMixin } from './OxyServices.assets';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
21
|
+
import { OxyServicesAccountsMixin } from './OxyServices.accounts';
|
|
22
|
+
import { OxyServicesConnectedAppsMixin } from './OxyServices.connectedApps';
|
|
23
23
|
import { OxyServicesLocationMixin } from './OxyServices.location';
|
|
24
24
|
import { OxyServicesAnalyticsMixin } from './OxyServices.analytics';
|
|
25
25
|
import { OxyServicesDevicesMixin } from './OxyServices.devices';
|
|
@@ -27,7 +27,6 @@ import { OxyServicesSecurityMixin } from './OxyServices.security';
|
|
|
27
27
|
import { OxyServicesUtilityMixin } from './OxyServices.utility';
|
|
28
28
|
import { OxyServicesFeaturesMixin } from './OxyServices.features';
|
|
29
29
|
import { OxyServicesTopicsMixin } from './OxyServices.topics';
|
|
30
|
-
import { OxyServicesManagedAccountsMixin } from './OxyServices.managedAccounts';
|
|
31
30
|
import { OxyServicesContactsMixin } from './OxyServices.contacts';
|
|
32
31
|
import { OxyServicesAppDataMixin } from './OxyServices.appData';
|
|
33
32
|
import { OxyServicesCivicMixin } from './OxyServices.civic';
|
|
@@ -56,15 +55,14 @@ type AllMixinInstances =
|
|
|
56
55
|
& InstanceType<ReturnType<typeof OxyServicesPaymentMixin<typeof OxyServicesBase>>>
|
|
57
56
|
& InstanceType<ReturnType<typeof OxyServicesReputationMixin<typeof OxyServicesBase>>>
|
|
58
57
|
& InstanceType<ReturnType<typeof OxyServicesAssetsMixin<typeof OxyServicesBase>>>
|
|
59
|
-
& InstanceType<ReturnType<typeof
|
|
60
|
-
& InstanceType<ReturnType<typeof
|
|
58
|
+
& InstanceType<ReturnType<typeof OxyServicesAccountsMixin<typeof OxyServicesBase>>>
|
|
59
|
+
& InstanceType<ReturnType<typeof OxyServicesConnectedAppsMixin<typeof OxyServicesBase>>>
|
|
61
60
|
& InstanceType<ReturnType<typeof OxyServicesLocationMixin<typeof OxyServicesBase>>>
|
|
62
61
|
& InstanceType<ReturnType<typeof OxyServicesAnalyticsMixin<typeof OxyServicesBase>>>
|
|
63
62
|
& InstanceType<ReturnType<typeof OxyServicesDevicesMixin<typeof OxyServicesBase>>>
|
|
64
63
|
& InstanceType<ReturnType<typeof OxyServicesSecurityMixin<typeof OxyServicesBase>>>
|
|
65
64
|
& InstanceType<ReturnType<typeof OxyServicesFeaturesMixin<typeof OxyServicesBase>>>
|
|
66
65
|
& InstanceType<ReturnType<typeof OxyServicesTopicsMixin<typeof OxyServicesBase>>>
|
|
67
|
-
& InstanceType<ReturnType<typeof OxyServicesManagedAccountsMixin<typeof OxyServicesBase>>>
|
|
68
66
|
& InstanceType<ReturnType<typeof OxyServicesContactsMixin<typeof OxyServicesBase>>>
|
|
69
67
|
& InstanceType<ReturnType<typeof OxyServicesAppDataMixin<typeof OxyServicesBase>>>
|
|
70
68
|
& InstanceType<ReturnType<typeof OxyServicesCivicMixin<typeof OxyServicesBase>>>
|
|
@@ -125,15 +123,19 @@ const MIXIN_PIPELINE: MixinFunction[] = [
|
|
|
125
123
|
OxyServicesPaymentMixin,
|
|
126
124
|
OxyServicesReputationMixin,
|
|
127
125
|
OxyServicesAssetsMixin,
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
// Unified account graph + the applications owned within it. The clean-cut
|
|
127
|
+
// replacement for the former managedAccounts + workspaces + applications
|
|
128
|
+
// (account-management) mixins.
|
|
129
|
+
OxyServicesAccountsMixin,
|
|
130
|
+
// OAuth-consent surface (public app identity + connected-app grants). Kept
|
|
131
|
+
// separate from account ownership.
|
|
132
|
+
OxyServicesConnectedAppsMixin,
|
|
130
133
|
OxyServicesLocationMixin,
|
|
131
134
|
OxyServicesAnalyticsMixin,
|
|
132
135
|
OxyServicesDevicesMixin,
|
|
133
136
|
OxyServicesSecurityMixin,
|
|
134
137
|
OxyServicesFeaturesMixin,
|
|
135
138
|
OxyServicesTopicsMixin,
|
|
136
|
-
OxyServicesManagedAccountsMixin,
|
|
137
139
|
OxyServicesContactsMixin,
|
|
138
140
|
OxyServicesAppDataMixin,
|
|
139
141
|
// Civic / Commons "Oxy ID" (public signed cards, Oxy ID QR payload)
|
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OxyServicesApplicationsMixin = OxyServicesApplicationsMixin;
|
|
4
|
-
const mixinHelpers_1 = require("./mixinHelpers");
|
|
5
|
-
function OxyServicesApplicationsMixin(Base) {
|
|
6
|
-
return class extends Base {
|
|
7
|
-
constructor(...args) {
|
|
8
|
-
super(...args);
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Resolve an OAuth client identifier to the owning application's PUBLIC
|
|
12
|
-
* identity. No authentication required — the API returns only sanitized,
|
|
13
|
-
* display-safe metadata ({@link PublicApplication}). Use this to render the
|
|
14
|
-
* requesting application's name/icon in consent, authorize, and device-flow
|
|
15
|
-
* approval UIs before any session exists.
|
|
16
|
-
*
|
|
17
|
-
* @param clientId - The OAuth `client_id` (an active credential's public
|
|
18
|
-
* key). URL-encoded before being placed in the path.
|
|
19
|
-
*/
|
|
20
|
-
async getPublicApplication(clientId) {
|
|
21
|
-
try {
|
|
22
|
-
const res = await this.makeRequest('GET', `/auth/oauth/client/${encodeURIComponent(clientId)}`, undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.MEDIUM });
|
|
23
|
-
return res.application;
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
throw this.handleError(error);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* List the OAuth-authorized applications the current user has connected —
|
|
31
|
-
* the third-party apps the user granted access to via the consent flow.
|
|
32
|
-
* Each entry is a {@link ConnectedApp} carrying the application's display
|
|
33
|
-
* identity, the granted scopes, and when the grant was first made and last
|
|
34
|
-
* exercised. Requires an authenticated session.
|
|
35
|
-
*
|
|
36
|
-
* Backed by `GET /auth/grants`. The response is briefly cached
|
|
37
|
-
* (identity-scoped); {@link revokeAppGrant} busts that cache so a revoke is
|
|
38
|
-
* reflected on the next read.
|
|
39
|
-
*/
|
|
40
|
-
async listConnectedApps() {
|
|
41
|
-
try {
|
|
42
|
-
return await this.makeRequest('GET', '/auth/grants', undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.SHORT });
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
throw this.handleError(error);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Revoke the current user's grant for a connected application, identified by
|
|
50
|
-
* its application `_id` (a {@link ConnectedApp.applicationId}, NOT a
|
|
51
|
-
* credential/client id — keyed by application so the revocation survives
|
|
52
|
-
* credential rotation). After this the application can no longer act on the
|
|
53
|
-
* user's behalf until it is re-authorized.
|
|
54
|
-
*
|
|
55
|
-
* Backed by `DELETE /auth/grants/:applicationId`. On success the cached
|
|
56
|
-
* connected-apps list (`GET:/auth/grants`) is invalidated so the next
|
|
57
|
-
* {@link listConnectedApps} read reflects the removal.
|
|
58
|
-
*
|
|
59
|
-
* @param applicationId - The connected application's Mongo `_id`.
|
|
60
|
-
*/
|
|
61
|
-
async revokeAppGrant(applicationId) {
|
|
62
|
-
try {
|
|
63
|
-
await this.makeRequest('DELETE', `/auth/grants/${applicationId}`, undefined, { cache: false });
|
|
64
|
-
// A revoke removes an entry from the user's connected-apps list; bust
|
|
65
|
-
// the cached `GET /auth/grants` so the next read re-fetches.
|
|
66
|
-
this.clearCacheEntry('GET:/auth/grants');
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
throw this.handleError(error);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* List applications the current user is an active member of.
|
|
74
|
-
*
|
|
75
|
-
* @param workspaceId - Optional workspace `_id` to scope the listing to
|
|
76
|
-
* applications belonging to that workspace. When provided it is appended
|
|
77
|
-
* as a `workspaceId` query parameter (URL-encoded). The query string is
|
|
78
|
-
* part of the request path, so the response cache keys on it
|
|
79
|
-
* automatically — scoped and unscoped lists never collide.
|
|
80
|
-
*/
|
|
81
|
-
async getApplications(workspaceId) {
|
|
82
|
-
try {
|
|
83
|
-
const path = workspaceId
|
|
84
|
-
? `/applications?workspaceId=${encodeURIComponent(workspaceId)}`
|
|
85
|
-
: '/applications';
|
|
86
|
-
const res = await this.makeRequest('GET', path, undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.MEDIUM });
|
|
87
|
-
return res.applications ?? [];
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
throw this.handleError(error);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Create a new application. The caller becomes its `owner`.
|
|
95
|
-
* @param data - Application configuration. Staff-only fields are ignored.
|
|
96
|
-
*/
|
|
97
|
-
async createApplication(data) {
|
|
98
|
-
try {
|
|
99
|
-
const res = await this.makeRequest('POST', '/applications', data, { cache: false });
|
|
100
|
-
// Bust every cached application list (unscoped + per-workspace) so the
|
|
101
|
-
// new application appears on the next `getApplications()` read.
|
|
102
|
-
this._invalidateApplicationLists();
|
|
103
|
-
return res.application;
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
throw this.handleError(error);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Fetch a single application by id.
|
|
111
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
112
|
-
*/
|
|
113
|
-
async getApplication(applicationId) {
|
|
114
|
-
try {
|
|
115
|
-
const res = await this.makeRequest('GET', `/applications/${applicationId}`, undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.LONG });
|
|
116
|
-
return res.application;
|
|
117
|
-
}
|
|
118
|
-
catch (error) {
|
|
119
|
-
throw this.handleError(error);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Update an application's mutable fields.
|
|
124
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
125
|
-
* @param data - Subset of updatable fields. Staff-only fields are ignored.
|
|
126
|
-
*/
|
|
127
|
-
async updateApplication(applicationId, data) {
|
|
128
|
-
try {
|
|
129
|
-
const res = await this.makeRequest('PATCH', `/applications/${applicationId}`, data, { cache: false });
|
|
130
|
-
// Bust the cached detail and every list (which embeds application
|
|
131
|
-
// fields) so neither serves the pre-update snapshot.
|
|
132
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}`);
|
|
133
|
-
this._invalidateApplicationLists();
|
|
134
|
-
return res.application;
|
|
135
|
-
}
|
|
136
|
-
catch (error) {
|
|
137
|
-
throw this.handleError(error);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Soft-delete an application (owner only).
|
|
142
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
143
|
-
*/
|
|
144
|
-
async deleteApplication(applicationId) {
|
|
145
|
-
try {
|
|
146
|
-
const result = await this.makeRequest('DELETE', `/applications/${applicationId}`, undefined, { cache: false });
|
|
147
|
-
// Bust every cached representation of the deleted application.
|
|
148
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}`);
|
|
149
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}/members`);
|
|
150
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}/credentials`);
|
|
151
|
-
this._invalidateApplicationLists();
|
|
152
|
-
return result;
|
|
153
|
-
}
|
|
154
|
-
catch (error) {
|
|
155
|
-
throw this.handleError(error);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* List members of an application.
|
|
160
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
161
|
-
*/
|
|
162
|
-
async getApplicationMembers(applicationId) {
|
|
163
|
-
try {
|
|
164
|
-
const res = await this.makeRequest('GET', `/applications/${applicationId}/members`, undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.MEDIUM });
|
|
165
|
-
return res.members ?? [];
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
throw this.handleError(error);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Add a member to an application.
|
|
173
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
174
|
-
* @param data - Target user's username or email and role (never `owner`).
|
|
175
|
-
* The server resolves `usernameOrEmail` to a user; an unknown value yields
|
|
176
|
-
* a 404 "User not found".
|
|
177
|
-
*/
|
|
178
|
-
async inviteApplicationMember(applicationId, data) {
|
|
179
|
-
try {
|
|
180
|
-
const res = await this.makeRequest('POST', `/applications/${applicationId}/members`, data, { cache: false });
|
|
181
|
-
this._invalidateApplicationMembership(applicationId);
|
|
182
|
-
return res.member;
|
|
183
|
-
}
|
|
184
|
-
catch (error) {
|
|
185
|
-
throw this.handleError(error);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Change a member's role.
|
|
190
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
191
|
-
* @param memberId - The member's Mongo `_id`.
|
|
192
|
-
* @param data - New role.
|
|
193
|
-
*/
|
|
194
|
-
async updateApplicationMember(applicationId, memberId, data) {
|
|
195
|
-
try {
|
|
196
|
-
const res = await this.makeRequest('PATCH', `/applications/${applicationId}/members/${memberId}`, data, { cache: false });
|
|
197
|
-
this._invalidateApplicationMembership(applicationId);
|
|
198
|
-
return res.member;
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
throw this.handleError(error);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Remove a member from an application.
|
|
206
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
207
|
-
* @param memberId - The member's Mongo `_id`.
|
|
208
|
-
*/
|
|
209
|
-
async removeApplicationMember(applicationId, memberId) {
|
|
210
|
-
try {
|
|
211
|
-
const result = await this.makeRequest('DELETE', `/applications/${applicationId}/members/${memberId}`, undefined, { cache: false });
|
|
212
|
-
this._invalidateApplicationMembership(applicationId);
|
|
213
|
-
return result;
|
|
214
|
-
}
|
|
215
|
-
catch (error) {
|
|
216
|
-
throw this.handleError(error);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Transfer ownership of an application to another member (owner only).
|
|
221
|
-
* Demotes the current owner to `admin` and promotes the target to `owner`.
|
|
222
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
223
|
-
* @param data - Target user id.
|
|
224
|
-
*/
|
|
225
|
-
async transferApplicationOwnership(applicationId, data) {
|
|
226
|
-
try {
|
|
227
|
-
const result = await this.makeRequest('POST', `/applications/${applicationId}/transfer-ownership`, data, { cache: false });
|
|
228
|
-
// Ownership change alters roles in the member list AND the detail, and
|
|
229
|
-
// can change which applications the caller "owns" in the list view.
|
|
230
|
-
this._invalidateApplicationMembership(applicationId);
|
|
231
|
-
this._invalidateApplicationLists();
|
|
232
|
-
return result;
|
|
233
|
-
}
|
|
234
|
-
catch (error) {
|
|
235
|
-
throw this.handleError(error);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* List an application's credentials. The response NEVER includes secrets.
|
|
240
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
241
|
-
*/
|
|
242
|
-
async getApplicationCredentials(applicationId) {
|
|
243
|
-
try {
|
|
244
|
-
const res = await this.makeRequest('GET', `/applications/${applicationId}/credentials`, undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.MEDIUM });
|
|
245
|
-
return res.credentials ?? [];
|
|
246
|
-
}
|
|
247
|
-
catch (error) {
|
|
248
|
-
throw this.handleError(error);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* Create a credential. The plaintext `secret` is returned exactly ONCE;
|
|
253
|
-
* the server stores only a hash and will never return it again.
|
|
254
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
255
|
-
* @param data - Credential configuration.
|
|
256
|
-
*/
|
|
257
|
-
async createApplicationCredential(applicationId, data) {
|
|
258
|
-
try {
|
|
259
|
-
const result = await this.makeRequest('POST', `/applications/${applicationId}/credentials`, data, { cache: false });
|
|
260
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}/credentials`);
|
|
261
|
-
return result;
|
|
262
|
-
}
|
|
263
|
-
catch (error) {
|
|
264
|
-
throw this.handleError(error);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Rotate a credential's secret. The new plaintext `secret` is returned
|
|
269
|
-
* exactly ONCE, along with audit fields: `rotatedFrom` (the previous
|
|
270
|
-
* credentialId) and `graceExpiresAt` (ISO string for the grace window during
|
|
271
|
-
* which the old credential is still honoured).
|
|
272
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
273
|
-
* @param credentialId - The credential's Mongo `_id`.
|
|
274
|
-
*/
|
|
275
|
-
async rotateApplicationCredential(applicationId, credentialId) {
|
|
276
|
-
try {
|
|
277
|
-
const result = await this.makeRequest('POST', `/applications/${applicationId}/credentials/${credentialId}/rotate`, undefined, { cache: false });
|
|
278
|
-
// Rotation changes credential status/audit fields surfaced by the
|
|
279
|
-
// credentials list (`rotatedFrom`, grace window, new active credential).
|
|
280
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}/credentials`);
|
|
281
|
-
return result;
|
|
282
|
-
}
|
|
283
|
-
catch (error) {
|
|
284
|
-
throw this.handleError(error);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Revoke a credential (`status='revoked'`). Revoked credentials can no
|
|
289
|
-
* longer authenticate.
|
|
290
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
291
|
-
* @param credentialId - The credential's Mongo `_id`.
|
|
292
|
-
*/
|
|
293
|
-
async revokeApplicationCredential(applicationId, credentialId) {
|
|
294
|
-
try {
|
|
295
|
-
const result = await this.makeRequest('DELETE', `/applications/${applicationId}/credentials/${credentialId}`, undefined, { cache: false });
|
|
296
|
-
// Revocation flips the credential's status in the cached list.
|
|
297
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}/credentials`);
|
|
298
|
-
return result;
|
|
299
|
-
}
|
|
300
|
-
catch (error) {
|
|
301
|
-
throw this.handleError(error);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Fetch usage statistics for an application.
|
|
306
|
-
* @param applicationId - The application's Mongo `_id`.
|
|
307
|
-
* @param period - Time window (defaults to the server default).
|
|
308
|
-
*/
|
|
309
|
-
async getApplicationUsage(applicationId, period) {
|
|
310
|
-
try {
|
|
311
|
-
return await this.makeRequest('GET', `/applications/${applicationId}/usage`, period ? { period } : undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.SHORT });
|
|
312
|
-
}
|
|
313
|
-
catch (error) {
|
|
314
|
-
throw this.handleError(error);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Bust every cached application list. `getApplications(workspaceId?)` keys
|
|
319
|
-
* the unscoped list as `GET:/applications` and each workspace-scoped list as
|
|
320
|
-
* `GET:/applications?workspaceId=<id>` (the query string is part of the URL
|
|
321
|
-
* path). A change to list membership (create/delete/ownership transfer)
|
|
322
|
-
* invalidates all of them, so we clear the unscoped entry plus every
|
|
323
|
-
* `?workspaceId=` variant via a prefix sweep. The prefix `GET:/applications?`
|
|
324
|
-
* matches only the query-string list variants, never the `GET:/applications/<id>…`
|
|
325
|
-
* detail/sub-resource keys.
|
|
326
|
-
*
|
|
327
|
-
* Internal helper (leading underscore); not part of the supported public
|
|
328
|
-
* surface. Public rather than `private` because mixins compose into an
|
|
329
|
-
* exported anonymous class, where TypeScript cannot represent a private
|
|
330
|
-
* member in the emitted declaration file (TS4094).
|
|
331
|
-
*/
|
|
332
|
-
_invalidateApplicationLists() {
|
|
333
|
-
this.clearCacheEntry('GET:/applications');
|
|
334
|
-
this.clearCacheByPrefix('GET:/applications?');
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Bust the cached member list and detail for an application after a
|
|
338
|
-
* membership mutation. The member list (`getApplicationMembers`) and the
|
|
339
|
-
* detail (`getApplication`, which can embed member counts) both go stale
|
|
340
|
-
* when the member set or a member's role changes.
|
|
341
|
-
*
|
|
342
|
-
* Internal helper (leading underscore); see `_invalidateApplicationLists`
|
|
343
|
-
* for why this is public rather than `private`.
|
|
344
|
-
*/
|
|
345
|
-
_invalidateApplicationMembership(applicationId) {
|
|
346
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}/members`);
|
|
347
|
-
this.clearCacheEntry(`GET:/applications/${applicationId}`);
|
|
348
|
-
}
|
|
349
|
-
};
|
|
350
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OxyServicesManagedAccountsMixin = OxyServicesManagedAccountsMixin;
|
|
4
|
-
function OxyServicesManagedAccountsMixin(Base) {
|
|
5
|
-
return class extends Base {
|
|
6
|
-
constructor(...args) {
|
|
7
|
-
super(...args);
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Create a new managed account (sub-account).
|
|
11
|
-
*
|
|
12
|
-
* The server creates a User document with `isManagedAccount: true` and links
|
|
13
|
-
* it to the authenticated user as owner. Invalidates the cached
|
|
14
|
-
* `GET /managed-accounts` list (~2-minute TTL, identity-scoped) so the next
|
|
15
|
-
* read includes the newly created account.
|
|
16
|
-
*/
|
|
17
|
-
async createManagedAccount(data) {
|
|
18
|
-
try {
|
|
19
|
-
const result = await this.makeRequest('POST', '/managed-accounts', data, {
|
|
20
|
-
cache: false,
|
|
21
|
-
});
|
|
22
|
-
this.clearCacheEntry('GET:/managed-accounts');
|
|
23
|
-
return result;
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
throw this.handleError(error);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* List all accounts the authenticated user manages.
|
|
31
|
-
*/
|
|
32
|
-
async getManagedAccounts() {
|
|
33
|
-
try {
|
|
34
|
-
return await this.makeRequest('GET', '/managed-accounts', undefined, {
|
|
35
|
-
cache: true,
|
|
36
|
-
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
throw this.handleError(error);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Get details for a specific managed account.
|
|
45
|
-
*/
|
|
46
|
-
async getManagedAccountDetails(accountId) {
|
|
47
|
-
try {
|
|
48
|
-
return await this.makeRequest('GET', `/managed-accounts/${accountId}`, undefined, {
|
|
49
|
-
cache: true,
|
|
50
|
-
cacheTTL: 2 * 60 * 1000,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
throw this.handleError(error);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Update a managed account's profile data.
|
|
59
|
-
* Requires owner or admin role.
|
|
60
|
-
*
|
|
61
|
-
* Invalidates both the cached detail (`GET /managed-accounts/<id>`) and the
|
|
62
|
-
* cached list (`GET /managed-accounts`, which embeds account profile data)
|
|
63
|
-
* so neither serves the pre-update snapshot within their ~2-minute TTL.
|
|
64
|
-
*/
|
|
65
|
-
async updateManagedAccount(accountId, data) {
|
|
66
|
-
try {
|
|
67
|
-
const result = await this.makeRequest('PUT', `/managed-accounts/${accountId}`, data, {
|
|
68
|
-
cache: false,
|
|
69
|
-
});
|
|
70
|
-
this.clearCacheEntry(`GET:/managed-accounts/${accountId}`);
|
|
71
|
-
this.clearCacheEntry('GET:/managed-accounts');
|
|
72
|
-
return result;
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
throw this.handleError(error);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Delete a managed account permanently.
|
|
80
|
-
* Requires owner role.
|
|
81
|
-
*
|
|
82
|
-
* Invalidates the cached detail and list responses so the deleted account
|
|
83
|
-
* is not served from cache.
|
|
84
|
-
*/
|
|
85
|
-
async deleteManagedAccount(accountId) {
|
|
86
|
-
try {
|
|
87
|
-
await this.makeRequest('DELETE', `/managed-accounts/${accountId}`, undefined, {
|
|
88
|
-
cache: false,
|
|
89
|
-
});
|
|
90
|
-
this.clearCacheEntry(`GET:/managed-accounts/${accountId}`);
|
|
91
|
-
this.clearCacheEntry('GET:/managed-accounts');
|
|
92
|
-
}
|
|
93
|
-
catch (error) {
|
|
94
|
-
throw this.handleError(error);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Add a manager to a managed account.
|
|
99
|
-
* Requires owner or admin role on the account.
|
|
100
|
-
*
|
|
101
|
-
* Mutates the account's `managers[]`, which is returned by the detail and
|
|
102
|
-
* list reads — invalidate both so they re-fetch the updated manager set.
|
|
103
|
-
*
|
|
104
|
-
* @param accountId - The managed account to add the manager to
|
|
105
|
-
* @param userId - The user to grant management access
|
|
106
|
-
* @param role - The role to assign: 'admin' or 'editor'
|
|
107
|
-
*/
|
|
108
|
-
async addManager(accountId, userId, role) {
|
|
109
|
-
try {
|
|
110
|
-
await this.makeRequest('POST', `/managed-accounts/${accountId}/managers`, { userId, role }, {
|
|
111
|
-
cache: false,
|
|
112
|
-
});
|
|
113
|
-
this.clearCacheEntry(`GET:/managed-accounts/${accountId}`);
|
|
114
|
-
this.clearCacheEntry('GET:/managed-accounts');
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
throw this.handleError(error);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Remove a manager from a managed account.
|
|
122
|
-
* Requires owner role.
|
|
123
|
-
*
|
|
124
|
-
* Invalidates the detail and list responses so the updated `managers[]`
|
|
125
|
-
* is observed on the next read (see `addManager`).
|
|
126
|
-
*
|
|
127
|
-
* @param accountId - The managed account
|
|
128
|
-
* @param userId - The manager to remove
|
|
129
|
-
*/
|
|
130
|
-
async removeManager(accountId, userId) {
|
|
131
|
-
try {
|
|
132
|
-
await this.makeRequest('DELETE', `/managed-accounts/${accountId}/managers/${userId}`, undefined, {
|
|
133
|
-
cache: false,
|
|
134
|
-
});
|
|
135
|
-
this.clearCacheEntry(`GET:/managed-accounts/${accountId}`);
|
|
136
|
-
this.clearCacheEntry('GET:/managed-accounts');
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
throw this.handleError(error);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
}
|