bruce-models 7.1.96 → 7.1.98

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.
@@ -372,6 +372,9 @@
372
372
  // Manage own records only (eg: own draft bookmarks within a Project View).
373
373
  // Only implemented for Bookmarks at the moment.
374
374
  EAction["MANAGE_OWN"] = "MANAGE_OWN";
375
+ // Full CRUD over every record this one owns, and nothing on this record beyond reading it.
376
+ // Eg: "manage_content:et:<id>" manages that type's Entities without editing the type.
377
+ EAction["MANAGE_CONTENT"] = "MANAGE_CONTENT";
375
378
  EAction["VIEW"] = "VIEW";
376
379
  EAction["CREATE"] = "CREATE";
377
380
  EAction["EDIT"] = "EDIT";
@@ -434,10 +437,16 @@
434
437
  * Builds a concept permission string.
435
438
  * Omit recordId for an account-wide permission, eg: "view:pv".
436
439
  * Pass recordId for a record-specific permission, eg: "view:pv:abc123".
440
+ * Pass ownedConcept to narrow it to one kind of record that record owns,
441
+ * eg: "edit:et:abc123:e" for that Entity Type's Entities and nothing else.
437
442
  */
438
- function buildPermission(action, concept, recordId) {
443
+ function buildPermission(action, concept, recordId, ownedConcept) {
439
444
  const base = `${action.toLowerCase()}:${concept}`;
440
- return recordId ? `${base}:${recordId}` : base;
445
+ if (!recordId) {
446
+ return base;
447
+ }
448
+ const record = `${base}:${recordId}`;
449
+ return ownedConcept ? `${record}:${ownedConcept}` : record;
441
450
  }
442
451
  AccountConcept.buildPermission = buildPermission;
443
452
  /**
@@ -474,11 +483,27 @@
474
483
  if (!matchedConcept) {
475
484
  return null;
476
485
  }
477
- const recordId = rest.length > matchedLen ? rest.substring(matchedLen + 1) : undefined;
486
+ const tail = rest.length > matchedLen ? rest.substring(matchedLen + 1) : undefined;
487
+ // A fourth segment narrows the grant to one kind of record the named record owns.
488
+ // Anything that is not a concept token stays part of the record ID.
489
+ let recordId = tail;
490
+ let ownedConcept;
491
+ if (tail) {
492
+ const lastColon = tail.lastIndexOf(":");
493
+ if (lastColon > 0) {
494
+ const candidate = tail.substring(lastColon + 1);
495
+ const matched = Object.values(EConcept).find(t => t === candidate);
496
+ if (matched) {
497
+ ownedConcept = matched;
498
+ recordId = tail.substring(0, lastColon);
499
+ }
500
+ }
501
+ }
478
502
  return {
479
503
  action: matchedAction,
480
504
  concept: matchedConcept,
481
- recordId
505
+ recordId,
506
+ ownedConcept
482
507
  };
483
508
  }
484
509
  AccountConcept.parsePermission = parsePermission;
@@ -2897,6 +2922,20 @@
2897
2922
  })(exports.AccountFeatures || (exports.AccountFeatures = {}));
2898
2923
 
2899
2924
  (function (AccountInvite) {
2925
+ // Error type returned when inviting a user who already has access to the account.
2926
+ // Their group membership is changed directly rather than offered to them.
2927
+ AccountInvite.ERROR_ALREADY_MEMBER = "AlreadyMember";
2928
+ /**
2929
+ * Returns whether a failed Create was refused because the user is already in the account.
2930
+ * @param error the value thrown by Create.
2931
+ * @returns
2932
+ */
2933
+ function IsAlreadyMemberError(error) {
2934
+ var _a, _b;
2935
+ const type = (_b = (_a = error === null || error === void 0 ? void 0 : error.ERROR) === null || _a === void 0 ? void 0 : _a.Type) !== null && _b !== void 0 ? _b : error === null || error === void 0 ? void 0 : error.Type;
2936
+ return type === AccountInvite.ERROR_ALREADY_MEMBER;
2937
+ }
2938
+ AccountInvite.IsAlreadyMemberError = IsAlreadyMemberError;
2900
2939
  /**
2901
2940
  * Possible invite statuses.
2902
2941
  */
@@ -2907,6 +2946,8 @@
2907
2946
  EStatus["Sent"] = "Sent";
2908
2947
  EStatus["NotSent"] = "Not sent";
2909
2948
  EStatus["Accepted"] = "Accepted";
2949
+ // Closed because the user accepted another invite to the same account.
2950
+ EStatus["Superseded"] = "Superseded";
2910
2951
  })(EStatus = AccountInvite.EStatus || (AccountInvite.EStatus = {}));
2911
2952
  /**
2912
2953
  * Returns whether an invite is still awaiting a response from its recipient.
@@ -2921,6 +2962,16 @@
2921
2962
  return invite.Status === EStatus.Sent || invite.Status === EStatus.NotSent;
2922
2963
  }
2923
2964
  AccountInvite.IsPending = IsPending;
2965
+ /**
2966
+ * Ways an invited user can prove they are who the invitation was addressed to.
2967
+ */
2968
+ let EIdentityProof;
2969
+ (function (EIdentityProof) {
2970
+ // Confirming the password they already hold.
2971
+ EIdentityProof["Password"] = "Password";
2972
+ // Signing in, by whichever method their account allows, and returning.
2973
+ EIdentityProof["Session"] = "Session";
2974
+ })(EIdentityProof = AccountInvite.EIdentityProof || (AccountInvite.EIdentityProof = {}));
2924
2975
  /**
2925
2976
  * Possible invite methods.
2926
2977
  */
@@ -2957,6 +3008,66 @@
2957
3008
  });
2958
3009
  }
2959
3010
  AccountInvite.GetByCode = GetByCode;
3011
+ /**
3012
+ * Returns one invite by its ID. Requires the session to be an account owner or admin.
3013
+ * @param params
3014
+ * @returns
3015
+ */
3016
+ function GetByID(params) {
3017
+ return __awaiter(this, void 0, void 0, function* () {
3018
+ let { api, id, req } = params;
3019
+ if (!api) {
3020
+ api = exports.ENVIRONMENT.Api().GetGuardianApi();
3021
+ }
3022
+ const invite = yield api.GET(`v3/accountInvite/${id}`, exports.Api.PrepReqParams(req));
3023
+ return {
3024
+ invite: invite
3025
+ };
3026
+ });
3027
+ }
3028
+ AccountInvite.GetByID = GetByID;
3029
+ /**
3030
+ * Returns a list of invites grouped by the invited user.
3031
+ * Paging covers users rather than invites, so a user's invitations never straddle a page.
3032
+ * @param params
3033
+ * @returns
3034
+ */
3035
+ function GetListByUser(params) {
3036
+ return __awaiter(this, void 0, void 0, function* () {
3037
+ const res = yield GetList(Object.assign(Object.assign({}, params), { groupByUser: true }));
3038
+ return {
3039
+ users: res.invites,
3040
+ totalCount: res.totalCount,
3041
+ hasNextPage: res.hasNextPage,
3042
+ userGroups: res.userGroups
3043
+ };
3044
+ });
3045
+ }
3046
+ AccountInvite.GetListByUser = GetListByUser;
3047
+ /**
3048
+ * Re-delivers an invitation that is still open, renewing its code and expiry.
3049
+ * @param params
3050
+ * @returns
3051
+ */
3052
+ function Resend(params) {
3053
+ return __awaiter(this, void 0, void 0, function* () {
3054
+ let { api, id, emailTemplateKey, req } = params;
3055
+ if (!api) {
3056
+ api = exports.ENVIRONMENT.Api().GetGuardianApi();
3057
+ }
3058
+ if (!id) {
3059
+ throw new Error("An invite ID must be provided.");
3060
+ }
3061
+ const invite = yield api.POST("v3/resendAccountInvite", {
3062
+ ID: id,
3063
+ "Email.Template": emailTemplateKey
3064
+ }, exports.Api.PrepReqParams(req));
3065
+ return {
3066
+ invite: invite
3067
+ };
3068
+ });
3069
+ }
3070
+ AccountInvite.Resend = Resend;
2960
3071
  /**
2961
3072
  * Returns a list of invites matching provided criteria.
2962
3073
  * For example you can get a list of invites for a specific account or user (or both).
@@ -2965,7 +3076,7 @@
2965
3076
  */
2966
3077
  function GetList(params) {
2967
3078
  return __awaiter(this, void 0, void 0, function* () {
2968
- let { api, accountId, userId, status, expired, expandUsers, expandGroups, pageSize, pageIndex, req } = params;
3079
+ let { api, accountId, userId, status, expired, expandUsers, expandGroups, groupByUser, pageSize, pageIndex, req } = params;
2969
3080
  if (!api) {
2970
3081
  api = exports.ENVIRONMENT.Api().GetGuardianApi();
2971
3082
  }
@@ -2992,6 +3103,9 @@
2992
3103
  if (expand.length) {
2993
3104
  urlParams.append("Expand", expand.join(","));
2994
3105
  }
3106
+ if (groupByUser) {
3107
+ urlParams.append("GroupBy", "User");
3108
+ }
2995
3109
  if (pageSize !== undefined && pageSize !== null) {
2996
3110
  urlParams.append("PageSize", String(pageSize));
2997
3111
  }
@@ -3028,19 +3142,23 @@
3028
3142
  */
3029
3143
  function Update(params) {
3030
3144
  return __awaiter(this, void 0, void 0, function* () {
3031
- let { api, code, id, status, groupIds, user, req } = params;
3145
+ let { api, code, id, status, groupIds, user, password, req } = params;
3032
3146
  if (!api) {
3033
3147
  api = exports.ENVIRONMENT.Api().GetGuardianApi();
3034
3148
  }
3035
3149
  if (!code && !id) {
3036
3150
  throw new Error("Either an invite ID or InviteCode must be provided.");
3037
3151
  }
3152
+ if (!status && !groupIds) {
3153
+ throw new Error("Either a status or User Groups must be provided.");
3154
+ }
3038
3155
  const invite = yield api.POST("v3/accountInvite", {
3039
3156
  ID: id,
3040
3157
  InviteCode: code,
3041
3158
  Status: status,
3042
3159
  "UserGroup.ID": groupIds,
3043
- User: user
3160
+ User: user,
3161
+ Password: password
3044
3162
  }, exports.Api.PrepReqParams(req));
3045
3163
  return {
3046
3164
  invite: invite
@@ -16625,13 +16743,21 @@
16625
16743
  EType["DataLabQuery"] = "DataLabQuery";
16626
16744
  EType["WorkflowTicket"] = "WorkflowTicket";
16627
16745
  })(EType = EntityTypeTrigger.EType || (EntityTypeTrigger.EType = {}));
16746
+ /**
16747
+ * Builds the Settings payload for a WorkflowTicket trigger.
16748
+ * @param params
16749
+ */
16628
16750
  function BuildWorkflowTicketSettings(params) {
16629
16751
  var _a;
16630
16752
  const settings = Object.assign(Object.assign({}, ((_a = params.extraSettings) !== null && _a !== void 0 ? _a : {})), { Condition: params.condition, WorkflowTicket: {
16631
- "Workflow.ItemType.ID": params.workflowItemTypeId,
16632
- "Workflow.Queue.ID": params.queueId,
16633
- "Workflow.ItemStatus.ID": params.statusId
16753
+ "Workflow.ItemType.ID": params.workflowItemTypeId
16634
16754
  } });
16755
+ if (params.queueId != null && params.queueId !== "") {
16756
+ settings.WorkflowTicket["Workflow.Queue.ID"] = params.queueId;
16757
+ }
16758
+ if (params.statusId != null && params.statusId !== "") {
16759
+ settings.WorkflowTicket["Workflow.ItemStatus.ID"] = params.statusId;
16760
+ }
16635
16761
  if (params.description != null && params.description !== "") {
16636
16762
  settings.WorkflowTicket.Description = params.description;
16637
16763
  }
@@ -22460,8 +22586,8 @@
22460
22586
  function ForgotPassword(params) {
22461
22587
  return __awaiter(this, void 0, void 0, function* () {
22462
22588
  let { api, accountId, email, req: reqParams } = params;
22463
- if (!accountId || !email) {
22464
- throw ("Account ID and email are required.");
22589
+ if (!email) {
22590
+ throw new Error("An email address is required.");
22465
22591
  }
22466
22592
  if (!api) {
22467
22593
  api = exports.ENVIRONMENT.Api().GetGuardianApi();
@@ -22470,21 +22596,9 @@
22470
22596
  if (accountId) {
22471
22597
  url += "?Account=" + accountId;
22472
22598
  }
22473
- const req = api.POST(url, {
22599
+ yield api.POST(url, {
22474
22600
  Email: email
22475
22601
  }, reqParams);
22476
- const prom = new Promise((res, rej) => __awaiter(this, void 0, void 0, function* () {
22477
- try {
22478
- const data = yield req;
22479
- res({
22480
- userId: data.ID
22481
- });
22482
- }
22483
- catch (e) {
22484
- rej(e);
22485
- }
22486
- }));
22487
- return prom;
22488
22602
  });
22489
22603
  }
22490
22604
  LoginUser.ForgotPassword = ForgotPassword;
@@ -22495,22 +22609,29 @@
22495
22609
  */
22496
22610
  function ForgotPasswordComplete(params) {
22497
22611
  return __awaiter(this, void 0, void 0, function* () {
22498
- let { api, code, userId, password, req: reqParams } = params;
22612
+ let { api, code, email, userId, password, req: reqParams } = params;
22499
22613
  if (!api) {
22500
22614
  api = exports.ENVIRONMENT.Api().GetGuardianApi();
22501
22615
  }
22502
- const { user } = yield Get({
22503
- api: api,
22504
- userId: userId,
22505
- accountId: "",
22506
- req: reqParams
22507
- });
22616
+ if (!email && !userId) {
22617
+ throw new Error("Either an email or a user ID must be provided.");
22618
+ }
22619
+ // Callers holding only an ID still need the address resolved, but a caller that already
22620
+ // knows it should not have to read the user record back to reset a password.
22621
+ if (!email && userId) {
22622
+ const { user } = yield Get({
22623
+ api: api,
22624
+ userId: userId,
22625
+ accountId: "",
22626
+ req: reqParams
22627
+ });
22628
+ email = user.Email;
22629
+ }
22508
22630
  const res = yield api.POST("v3/userForgotPassword/complete", {
22509
22631
  ID: userId,
22510
- Email: user.Email,
22632
+ Email: email,
22511
22633
  ActivationCode: code,
22512
- Password: password,
22513
- FullName: user.FullName
22634
+ Password: password
22514
22635
  }, reqParams);
22515
22636
  return {
22516
22637
  user: res
@@ -23157,7 +23278,7 @@
23157
23278
  })(exports.UrlUtils || (exports.UrlUtils = {}));
23158
23279
 
23159
23280
  // This is updated with the package.json version on build.
23160
- const VERSION = "7.1.96";
23281
+ const VERSION = "7.1.98";
23161
23282
 
23162
23283
  exports.VERSION = VERSION;
23163
23284
  exports.AbstractApi = AbstractApi;