grm-shared-library 1.1.247 → 1.1.249

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 (41) hide show
  1. package/dist/cjs/kafka/dtos/user/guardians-changed-payload.dto.js +66 -0
  2. package/dist/cjs/kafka/dtos/user/guardians-changed-payload.dto.js.map +1 -0
  3. package/dist/cjs/kafka/index.js +1 -0
  4. package/dist/cjs/kafka/index.js.map +1 -1
  5. package/dist/cjs/kafka/topics.js +4 -0
  6. package/dist/cjs/kafka/topics.js.map +1 -1
  7. package/dist/cjs/modules/notification/dtos/unregister-device-token.dto.js +43 -0
  8. package/dist/cjs/modules/notification/dtos/unregister-device-token.dto.js.map +1 -0
  9. package/dist/cjs/modules/notification/index.js +2 -0
  10. package/dist/cjs/modules/notification/index.js.map +1 -1
  11. package/dist/cjs/modules/user/dtos/guardian-identifier.dto.js +2 -2
  12. package/dist/cjs/modules/user/dtos/guardian-identifier.dto.js.map +1 -1
  13. package/dist/cjs/modules/user/index.js +1 -0
  14. package/dist/cjs/modules/user/index.js.map +1 -1
  15. package/dist/cjs/modules/user/utils/app-account.util.js +90 -0
  16. package/dist/cjs/modules/user/utils/app-account.util.js.map +1 -0
  17. package/dist/esm/kafka/dtos/user/guardians-changed-payload.dto.js +62 -0
  18. package/dist/esm/kafka/dtos/user/guardians-changed-payload.dto.js.map +1 -0
  19. package/dist/esm/kafka/index.js +1 -0
  20. package/dist/esm/kafka/index.js.map +1 -1
  21. package/dist/esm/kafka/topics.js +4 -0
  22. package/dist/esm/kafka/topics.js.map +1 -1
  23. package/dist/esm/modules/notification/dtos/unregister-device-token.dto.js +38 -0
  24. package/dist/esm/modules/notification/dtos/unregister-device-token.dto.js.map +1 -0
  25. package/dist/esm/modules/notification/index.js +2 -0
  26. package/dist/esm/modules/notification/index.js.map +1 -1
  27. package/dist/esm/modules/user/dtos/guardian-identifier.dto.js +2 -2
  28. package/dist/esm/modules/user/dtos/guardian-identifier.dto.js.map +1 -1
  29. package/dist/esm/modules/user/index.js +1 -0
  30. package/dist/esm/modules/user/index.js.map +1 -1
  31. package/dist/esm/modules/user/utils/app-account.util.js +83 -0
  32. package/dist/esm/modules/user/utils/app-account.util.js.map +1 -0
  33. package/dist/types/kafka/dtos/user/guardians-changed-payload.dto.d.ts +32 -0
  34. package/dist/types/kafka/index.d.ts +1 -0
  35. package/dist/types/kafka/topics.d.ts +1 -0
  36. package/dist/types/modules/notification/dtos/unregister-device-token.dto.d.ts +20 -0
  37. package/dist/types/modules/notification/index.d.ts +1 -0
  38. package/dist/types/modules/user/index.d.ts +1 -0
  39. package/dist/types/modules/user/interfaces/guardian.d.ts +7 -0
  40. package/dist/types/modules/user/utils/app-account.util.d.ts +59 -0
  41. package/package.json +5 -5
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.GuardiansChangedPayloadDto = exports.GuardiansChangedReason = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ /** What changed about somebody's guardians - for logs and analytics; every reason means "refresh". */
15
+ var GuardiansChangedReason;
16
+ (function (GuardiansChangedReason) {
17
+ /** A guardian was added. */
18
+ GuardiansChangedReason["ADDED"] = "ADDED";
19
+ /** A guardian was removed by the person they guard. */
20
+ GuardiansChangedReason["REMOVED"] = "REMOVED";
21
+ /** Another guardian became the primary one. */
22
+ GuardiansChangedReason["PRIMARY_CHANGED"] = "PRIMARY_CHANGED";
23
+ /** A guardian on the list by phone number proved that number in the same organization's app, and is now an app guardian. */
24
+ GuardiansChangedReason["PROMOTED"] = "PROMOTED";
25
+ /** An app guardian's account was deleted; they stay on the list by phone number. */
26
+ GuardiansChangedReason["DEMOTED"] = "DEMOTED";
27
+ /** A guardian stopped looking after one of their dependents. */
28
+ GuardiansChangedReason["DEPENDENT_REMOVED"] = "DEPENDENT_REMOVED";
29
+ })(GuardiansChangedReason || (exports.GuardiansChangedReason = GuardiansChangedReason = {}));
30
+ /**
31
+ * Payload of `KAFKA_TOPICS.GUARDIANS_CHANGED`: somebody's guardian list changed,
32
+ * and these people's apps should read their guardians and dependents again.
33
+ *
34
+ * Ids only - no names, numbers or relationships. The apps read the lists through
35
+ * the guardian API, which applies its own access rules.
36
+ */
37
+ class GuardiansChangedPayloadDto {
38
+ }
39
+ exports.GuardiansChangedPayloadDto = GuardiansChangedPayloadDto;
40
+ __decorate([
41
+ (0, class_validator_1.IsInt)(),
42
+ (0, class_validator_1.IsPositive)(),
43
+ __metadata("design:type", Number)
44
+ ], GuardiansChangedPayloadDto.prototype, "organizationId", void 0);
45
+ __decorate([
46
+ (0, class_validator_1.IsInt)(),
47
+ (0, class_validator_1.IsPositive)(),
48
+ __metadata("design:type", Number)
49
+ ], GuardiansChangedPayloadDto.prototype, "dependentId", void 0);
50
+ __decorate([
51
+ (0, class_validator_1.IsArray)(),
52
+ (0, class_validator_1.ArrayMinSize)(1),
53
+ (0, class_validator_1.ArrayMaxSize)(100),
54
+ (0, class_validator_1.IsInt)({ each: true }),
55
+ (0, class_validator_1.IsPositive)({ each: true }),
56
+ __metadata("design:type", Array)
57
+ ], GuardiansChangedPayloadDto.prototype, "userIds", void 0);
58
+ __decorate([
59
+ (0, class_validator_1.IsEnum)(GuardiansChangedReason),
60
+ __metadata("design:type", String)
61
+ ], GuardiansChangedPayloadDto.prototype, "reason", void 0);
62
+ __decorate([
63
+ (0, class_validator_1.IsISO8601)(),
64
+ __metadata("design:type", String)
65
+ ], GuardiansChangedPayloadDto.prototype, "occurredAt", void 0);
66
+ //# sourceMappingURL=guardians-changed-payload.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardians-changed-payload.dto.js","sourceRoot":"","sources":["../../../../../src/kafka/dtos/user/guardians-changed-payload.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAA4G;AAE5G,sGAAsG;AACtG,IAAY,sBAaX;AAbD,WAAY,sBAAsB;IAC9B,4BAA4B;IAC5B,yCAAe,CAAA;IACf,uDAAuD;IACvD,6CAAmB,CAAA;IACnB,+CAA+C;IAC/C,6DAAmC,CAAA;IACnC,4HAA4H;IAC5H,+CAAqB,CAAA;IACrB,oFAAoF;IACpF,6CAAmB,CAAA;IACnB,gEAAgE;IAChE,iEAAuC,CAAA;AAC3C,CAAC,EAbW,sBAAsB,sCAAtB,sBAAsB,QAajC;AAED;;;;;;GAMG;AACH,MAAa,0BAA0B;CAwBtC;AAxBD,gEAwBC;AApBG;IAFC,IAAA,uBAAK,GAAE;IACP,IAAA,4BAAU,GAAE;;kEACW;AAKxB;IAFC,IAAA,uBAAK,GAAE;IACP,IAAA,4BAAU,GAAE;;+DACQ;AAQrB;IALC,IAAA,yBAAO,GAAE;IACT,IAAA,8BAAY,EAAC,CAAC,CAAC;IACf,IAAA,8BAAY,EAAC,GAAG,CAAC;IACjB,IAAA,uBAAK,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACrB,IAAA,4BAAU,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;;2DACR;AAGnB;IADC,IAAA,wBAAM,EAAC,sBAAsB,CAAC;;0DACC;AAGhC;IADC,IAAA,2BAAS,GAAE;;8DACQ"}
@@ -24,4 +24,5 @@ __exportStar(require("./dtos/otp/create-otp-payload.dto"), exports);
24
24
  __exportStar(require("./dtos/otp/otp-payload.dto"), exports);
25
25
  __exportStar(require("./dtos/password/password-reset-payload.dto"), exports);
26
26
  __exportStar(require("./dtos/account-deletion/account-deletion-request-payload.dto"), exports);
27
+ __exportStar(require("./dtos/user/guardians-changed-payload.dto"), exports);
27
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kafka/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,mDAAiC;AACjC,8EAA4D;AAC5D,uEAAqD;AACrD,iFAA+D;AAC/D,0EAAwD;AACxD,oEAAkD;AAClD,6DAA2C;AAC3C,6EAA2D;AAC3D,+FAA6E"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kafka/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,mDAAiC;AACjC,8EAA4D;AAC5D,uEAAqD;AACrD,iFAA+D;AAC/D,0EAAwD;AACxD,oEAAkD;AAClD,6DAA2C;AAC3C,6EAA2D;AAC3D,+FAA6E;AAC7E,4EAA0D"}
@@ -12,6 +12,10 @@ exports.KAFKA_TOPICS = {
12
12
  USER_CREATED: 'user.created',
13
13
  USER_UPDATED: 'user.updated',
14
14
  USER_DELETED: 'user.deleted',
15
+ // Somebody's guardians or dependents changed (producer: clarion-authentication;
16
+ // payload GuardiansChangedPayloadDto; consumer: clarion-notification, which
17
+ // sends each affected person a silent push so their app refreshes). Ids only.
18
+ GUARDIANS_CHANGED: 'user.guardians.changed.v1',
15
19
  // Org. ORG_CREATED is published by clarion-organization after commit
16
20
  // (payload OrganizationCreatedEvent); clarion-incident provisions the Safety
17
21
  // Alerts category from it.
@@ -1 +1 @@
1
- {"version":3,"file":"topics.js","sourceRoot":"","sources":["../../../src/kafka/topics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"topics.js","sourceRoot":"","sources":["../../../src/kafka/topics.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG;IACxB,OAAO;IACP,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,6BAA6B,EAAE,+BAA+B;IAC9D,6BAA6B,EAAE,+BAA+B;IAC9D,OAAO;IACP,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,gFAAgF;IAChF,4EAA4E;IAC5E,8EAA8E;IAC9E,iBAAiB,EAAE,2BAA2B;IAC9C,qEAAqE;IACrE,6EAA6E;IAC7E,2BAA2B;IAC3B,WAAW,EAAE,aAAa;IAC1B,WAAW,EAAE,aAAa;IAC1B,WAAW,EAAE,aAAa;IAC1B,MAAM;IACN,YAAY,EAAE,eAAe;IAC7B,aAAa,EAAE,eAAe;IAC9B,WAAW;IACX,cAAc,EAAE,gBAAgB;IAChC,WAAW;IACX,gBAAgB,EAAE,kBAAkB;IACpC,gBAAgB,EAAE,kBAAkB;IACpC,uBAAuB,EAAE,yBAAyB;IAClD,sBAAsB,EAAE,wBAAwB;IAChD,yBAAyB,EAAE,2BAA2B;IACtD,wBAAwB,EAAE,0BAA0B;IACpD,0BAA0B,EAAE,4BAA4B;IACxD,sBAAsB,EAAE,wBAAwB;IAChD,iBAAiB,EAAE,mBAAmB;IACtC,2BAA2B,EAAE,6BAA6B;IAC1D,yCAAyC,EAAE,2CAA2C;IACtF,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,6EAA6E;IAC7E,uCAAuC,EAAE,4CAA4C;IACrF,8CAA8C,EAAE,mDAAmD;IACnG,sDAAsD,EAClD,2DAA2D;IAC/D,qEAAqE;IACrE,+BAA+B;IAC/B,0CAA0C,EAAE,4DAA4D;IACxG,OAAO;IACP,oBAAoB,EAAE,sBAAsB;IAC5C,yBAAyB,EAAE,2BAA2B;IACtD,qBAAqB,EAAE,uBAAuB;IAC9C,OAAO;IACP,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,aAAa;IAC1B,OAAO;IACP,iBAAiB,EAAE,mBAAmB;IACtC,oBAAoB,EAAE,sBAAsB;IAC5C,WAAW;IACX,qBAAqB,EAAE,uBAAuB;IAC9C,uBAAuB,EAAE,yBAAyB;IAClD,qBAAqB,EAAE,uBAAuB;IAC9C,sBAAsB,EAAE,wBAAwB;IAChD,qBAAqB,EAAE,uBAAuB;IAC9C,mBAAmB,EAAE,qBAAqB;IAC1C,qBAAqB,EAAE,uBAAuB;IAC9C,oBAAoB,EAAE,sBAAsB;IAC5C,wBAAwB,EAAE,0BAA0B;IACpD,wBAAwB,EAAE,0BAA0B;IACpD,wBAAwB,EAAE,0BAA0B;IACpD,iEAAiE;IACjE,iBAAiB,EAAE,oCAAoC;IACvD,eAAe,EAAE,kCAAkC;IACnD,wBAAwB,EAAE,6BAA6B;IACvD,wBAAwB,EAAE,6BAA6B;IACvD,wBAAwB,EAAE,6BAA6B;IACvD,wEAAwE;IACxE,+DAA+D;IAC/D,yBAAyB,EAAE,uCAAuC;IAClE,yBAAyB,EAAE,uCAAuC;IAClE,yBAAyB,EAAE,uCAAuC;IAClE,wCAAwC,EACpC,sDAAsD;IAC1D,gCAAgC,EAAE,8CAA8C;IAChF,iFAAiF;IACjF,wBAAwB,EAAE,6BAA6B;IACvD,+BAA+B,EAAE,oCAAoC;IACrE,iFAAiF;IACjF,2EAA2E;IAC3E,4EAA4E;IAC5E,2EAA2E;IAC3E,iEAAiE;IACjE,sBAAsB,EAAE,2BAA2B;IACnD,sBAAsB,EAAE,2BAA2B;IACnD,uBAAuB,EAAE,4BAA4B;IACrD,6BAA6B,EAAE,kCAAkC;IACjE,+BAA+B,EAAE,oCAAoC;IACrE,8BAA8B,EAAE,mCAAmC;IACnE,+BAA+B,EAAE,oCAAoC;IACrE,4BAA4B,EAAE,iCAAiC;IAC/D,uBAAuB,EAAE,4BAA4B;IACrD,qBAAqB,EAAE,0BAA0B;IACjD,uBAAuB,EAAE,4BAA4B;IACrD,0BAA0B,EAAE,+BAA+B;IAC3D,2BAA2B,EAAE,gCAAgC;IAC7D,wBAAwB,EAAE,6BAA6B;IACvD,wBAAwB,EAAE,6BAA6B;IACvD,yBAAyB,EAAE,8BAA8B;IACzD,0BAA0B,EAAE,+BAA+B;IAC3D,oCAAoC,EAAE,yCAAyC;IAC/E,iCAAiC,EAAE,sCAAsC;IACzE,4BAA4B,EAAE,iCAAiC;IAC/D,+BAA+B,EAAE,oCAAoC;IACrE,wEAAwE;IACxE,8EAA8E;IAC9E,mDAAmD;IACnD,oBAAoB,EAAE,yBAAyB;IAC/C,sBAAsB,EAAE,2BAA2B;IACnD,kBAAkB,EAAE,uBAAuB;IAC3C,0BAA0B,EAAE,+BAA+B;IAC3D,+EAA+E;IAC/E,8DAA8D;IAC9D,iBAAiB,EAAE,6BAA6B;IAChD,4BAA4B,EAAE,wCAAwC;IACtE,mBAAmB,EAAE,+BAA+B;IACpD,uBAAuB,EAAE,mCAAmC;IAC5D,eAAe,EAAE,2BAA2B;IAC5C,2EAA2E;IAC3E,uEAAuE;IACvE,6EAA6E;IAC7E,+BAA+B;IAC/B,qCAAqC,EAAE,0CAA0C;IACjF,oBAAoB,EAAE,yBAAyB;IAC/C,8BAA8B,EAAE,mCAAmC;IACnE,0EAA0E;IAC1E,0EAA0E;IAC1E,yCAAyC,EAAE,8CAA8C;IACzF,sCAAsC,EAAE,wDAAwD;CACnG,CAAC"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.UnregisterDeviceTokenRequestDto = exports.UnregisterDeviceTokenDto = void 0;
13
+ const swagger_1 = require("@nestjs/swagger");
14
+ const class_validator_1 = require("class-validator");
15
+ /**
16
+ * Signing out of the app: this device stops receiving the signed-out account's
17
+ * pushes (`POST /api/push-notifications/device-tokens/unregister`). Before this a
18
+ * signed-out phone kept receiving that person's SOS alerts and guardian pushes
19
+ * until somebody else signed in on it.
20
+ */
21
+ class UnregisterDeviceTokenDto {
22
+ }
23
+ exports.UnregisterDeviceTokenDto = UnregisterDeviceTokenDto;
24
+ __decorate([
25
+ (0, swagger_1.ApiProperty)({ description: 'The FCM/APNs registration token of this device', maxLength: 4096 }),
26
+ (0, class_validator_1.IsString)(),
27
+ (0, class_validator_1.IsNotEmpty)(),
28
+ (0, class_validator_1.MaxLength)(4096),
29
+ __metadata("design:type", String)
30
+ ], UnregisterDeviceTokenDto.prototype, "deviceToken", void 0);
31
+ /**
32
+ * The gateway's request to clarion-notification: the token, and the SIGNED-IN caller
33
+ * it must belong to. A token registered to anybody else is left alone.
34
+ */
35
+ class UnregisterDeviceTokenRequestDto extends UnregisterDeviceTokenDto {
36
+ }
37
+ exports.UnregisterDeviceTokenRequestDto = UnregisterDeviceTokenRequestDto;
38
+ __decorate([
39
+ (0, class_validator_1.IsInt)(),
40
+ (0, class_validator_1.IsPositive)(),
41
+ __metadata("design:type", Number)
42
+ ], UnregisterDeviceTokenRequestDto.prototype, "userId", void 0);
43
+ //# sourceMappingURL=unregister-device-token.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unregister-device-token.dto.js","sourceRoot":"","sources":["../../../../../src/modules/notification/dtos/unregister-device-token.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAAqF;AAErF;;;;;GAKG;AACH,MAAa,wBAAwB;CAMpC;AAND,4DAMC;AADG;IAJC,IAAA,qBAAW,EAAC,EAAE,WAAW,EAAE,gDAAgD,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC/F,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,EAAC,IAAI,CAAC;;6DACK;AAGzB;;;GAGG;AACH,MAAa,+BAAgC,SAAQ,wBAAwB;CAI5E;AAJD,0EAIC;AADG;IAFC,IAAA,uBAAK,GAAE;IACP,IAAA,4BAAU,GAAE;;+DACG"}
@@ -48,4 +48,6 @@ __exportStar(require("./dtos/alert-acknowledgement.dto"), exports);
48
48
  // Notification Analytics (GET /admin/analytics, through the gateway's /notifications/admin/analytics)
49
49
  __exportStar(require("./interfaces/notification-analytics"), exports);
50
50
  __exportStar(require("./dtos/notification-analytics-query.dto"), exports);
51
+ // Signing out: the device stops receiving the account's pushes
52
+ __exportStar(require("./dtos/unregister-device-token.dto"), exports);
51
53
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/notification/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,QAAQ;AACR,oEAAkD;AAClD,iEAA+C;AAC/C,mEAAiD;AACjD,2EAAyD;AACzD,uEAAqD;AACrD,+DAA6C;AAC7C,0EAAwD;AACxD,yEAAuD;AACvD,0EAAwD;AACxD,4EAA0D;AAE1D,4CAA4C;AAC5C,gEAA8C;AAC9C,kEAAgD;AAChD,+DAA6C;AAC7C,iEAA+C;AAC/C,4EAA0D;AAE1D,0CAA0C;AAC1C,gEAA8C;AAC9C,kEAAgD;AAEhD,kEAAkE;AAClE,kFAAgE;AAChE,gFAA8D;AAC9D,wEAAsD;AACtD,mEAAiD;AAEjD,wFAAwF;AACxF,oEAAkD;AAClD,kEAAgD;AAChD,2EAAyD;AAEzD,oHAAoH;AACpH,mEAAiD;AAEjD,sGAAsG;AACtG,sEAAoD;AACpD,0EAAwD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/notification/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,QAAQ;AACR,oEAAkD;AAClD,iEAA+C;AAC/C,mEAAiD;AACjD,2EAAyD;AACzD,uEAAqD;AACrD,+DAA6C;AAC7C,0EAAwD;AACxD,yEAAuD;AACvD,0EAAwD;AACxD,4EAA0D;AAE1D,4CAA4C;AAC5C,gEAA8C;AAC9C,kEAAgD;AAChD,+DAA6C;AAC7C,iEAA+C;AAC/C,4EAA0D;AAE1D,0CAA0C;AAC1C,gEAA8C;AAC9C,kEAAgD;AAEhD,kEAAkE;AAClE,kFAAgE;AAChE,gFAA8D;AAC9D,wEAAsD;AACtD,mEAAiD;AAEjD,wFAAwF;AACxF,oEAAkD;AAClD,kEAAgD;AAChD,2EAAyD;AAEzD,oHAAoH;AACpH,mEAAiD;AAEjD,sGAAsG;AACtG,sEAAoD;AACpD,0EAAwD;AAExD,+DAA+D;AAC/D,qEAAmD"}
@@ -17,7 +17,7 @@ class GuardianIdentifierDto {
17
17
  exports.GuardianIdentifierDto = GuardianIdentifierDto;
18
18
  __decorate([
19
19
  (0, swagger_1.ApiProperty)({
20
- description: 'Phone number for external guardian',
20
+ description: 'Phone number of an external guardian (older apps). Prefer relationshipId, which names either kind.',
21
21
  example: '+1234567890',
22
22
  required: false,
23
23
  type: 'string'
@@ -28,7 +28,7 @@ __decorate([
28
28
  ], GuardianIdentifierDto.prototype, "phoneNumber", void 0);
29
29
  __decorate([
30
30
  (0, swagger_1.ApiProperty)({
31
- description: 'Relationship ID for system guardian',
31
+ description: 'The guardian entry id - `id` of an app-user guardian relation or of an external guardian (since grm-shared-library 1.1.248)',
32
32
  example: 789,
33
33
  required: false,
34
34
  type: 'number'
@@ -1 +1 @@
1
- {"version":3,"file":"guardian-identifier.dto.js","sourceRoot":"","sources":["../../../../../src/modules/user/dtos/guardian-identifier.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAA6E;AAE7E,MAAa,qBAAqB;CAoBjC;AApBD,sDAoBC;AAXG;IARC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,oCAAoC;QACjD,OAAO,EAAE,aAAa;QACtB,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,QAAQ;KACjB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;0DACQ;AAUrB;IARC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,qCAAqC;QAClD,OAAO,EAAE,GAAG;QACZ,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,QAAQ;KACjB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;6DACW"}
1
+ {"version":3,"file":"guardian-identifier.dto.js","sourceRoot":"","sources":["../../../../../src/modules/user/dtos/guardian-identifier.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8C;AAC9C,qDAA6E;AAE7E,MAAa,qBAAqB;CAoBjC;AApBD,sDAoBC;AAXG;IARC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,oGAAoG;QACjH,OAAO,EAAE,aAAa;QACtB,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,QAAQ;KACjB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;0DACQ;AAUrB;IARC,IAAA,qBAAW,EAAC;QACT,WAAW,EAAE,6HAA6H;QAC1I,OAAO,EAAE,GAAG;QACZ,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,QAAQ;KACjB,CAAC;IACD,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;;6DACW"}
@@ -32,4 +32,5 @@ __exportStar(require("./interfaces/guardian"), exports);
32
32
  __exportStar(require("./interfaces/guardian-relation"), exports);
33
33
  __exportStar(require("./interfaces/guardians-response"), exports);
34
34
  __exportStar(require("./interfaces/account-analytics"), exports);
35
+ __exportStar(require("./utils/app-account.util"), exports);
35
36
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/user/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,yDAAuC;AACvC,sDAAoC;AACpC,iEAA+C;AAC/C,sEAAoD;AACpD,6EAA2D;AAC3D,+EAA6D;AAC7D,yEAAuD;AAEvD,2DAAyC;AACzC,qEAAmD;AACnD,wEAAsD;AAEtD,oDAAkC;AAClC,4DAA0C;AAC1C,4DAA0C;AAC1C,wDAAsC;AACtC,iEAA+C;AAC/C,kEAAgD;AAChD,iEAA+C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/user/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,yDAAuC;AACvC,sDAAoC;AACpC,iEAA+C;AAC/C,sEAAoD;AACpD,6EAA2D;AAC3D,+EAA6D;AAC7D,yEAAuD;AAEvD,2DAAyC;AACzC,qEAAmD;AACnD,wEAAsD;AAEtD,oDAAkC;AAClC,4DAA0C;AAC1C,4DAA0C;AAC1C,wDAAsC;AACtC,iEAA+C;AAC/C,kEAAgD;AAChD,iEAA+C;AAE/C,2DAAyC"}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.APP_ACCOUNT_ERROR_CODES = exports.APP_ACCOUNT_ROLE = void 0;
4
+ exports.isAppAccount = isAppAccount;
5
+ exports.hasAppRole = hasAppRole;
6
+ exports.parseAppOrganizations = parseAppOrganizations;
7
+ exports.isAccountFromAnotherApp = isAccountFromAnotherApp;
8
+ const role_enum_1 = require("../../role/enums/role.enum");
9
+ /**
10
+ * App accounts and staff accounts.
11
+ *
12
+ * Each brand's mobile app (G4S Kenya, GeoSHIELD, SGA Security, ...) is its own
13
+ * product for one organization's customers, so an account made in one app is an
14
+ * account with that organization only. Signing in to another brand's app means
15
+ * registering with that brand. One person may therefore hold several app
16
+ * accounts - one per organization - with the same phone number and e-mail.
17
+ *
18
+ * Staff (Super-Admin, organization and control-centre staff, responders,
19
+ * corporate-client admins) keep one platform-wide account each: their e-mail and
20
+ * phone number stay unique across the whole platform.
21
+ *
22
+ * An APP ACCOUNT is one whose only role is Mobile-User. That is the same rule the
23
+ * database's unique indexes use (`roles = '{Mobile-User}'`), so code and schema
24
+ * can never disagree about which kind an account is. An account holding
25
+ * Mobile-User beside a staff role is a staff account that also uses an app.
26
+ */
27
+ exports.APP_ACCOUNT_ROLE = role_enum_1.Roles.MOBILE_USER;
28
+ /** An account whose only role is Mobile-User: unique within its organization, not platform-wide. */
29
+ function isAppAccount(roles) {
30
+ return Array.isArray(roles) && roles.length === 1 && roles[0] === exports.APP_ACCOUNT_ROLE;
31
+ }
32
+ /** Holds the Mobile-User role, alone or beside staff roles: someone who can use a brand's app. */
33
+ function hasAppRole(roles) {
34
+ return Array.isArray(roles) && roles.includes(exports.APP_ACCOUNT_ROLE);
35
+ }
36
+ /**
37
+ * Parses `APP_ORGANIZATIONS`. Blank means "none configured". A malformed entry
38
+ * throws: a typo here would let an app sign people in to the wrong organization,
39
+ * so it must stop the service at boot rather than be skipped.
40
+ */
41
+ function parseAppOrganizations(raw) {
42
+ const map = new Map();
43
+ for (const entry of String(raw !== null && raw !== void 0 ? raw : '').split(',')) {
44
+ const trimmed = entry.trim();
45
+ if (!trimmed)
46
+ continue;
47
+ const match = /^([A-Za-z0-9_-]+)\s*:\s*(\d+)$/.exec(trimmed);
48
+ if (!match)
49
+ throw new Error(`APP_ORGANIZATIONS: "${trimmed}" is not <appId>:<organizationId>`);
50
+ const [, appId, id] = match;
51
+ const organizationId = Number(id);
52
+ if (!Number.isSafeInteger(organizationId) || organizationId <= 0) {
53
+ throw new Error(`APP_ORGANIZATIONS: "${trimmed}" names no valid organization`);
54
+ }
55
+ const existing = map.get(appId);
56
+ if (existing !== undefined && existing !== organizationId) {
57
+ throw new Error(`APP_ORGANIZATIONS: ${appId} is given two organizations (${existing} and ${organizationId})`);
58
+ }
59
+ map.set(appId, organizationId);
60
+ }
61
+ return map;
62
+ }
63
+ /**
64
+ * Whether a signed-in account is being used from another organization's app: the
65
+ * request names an app (`X-App-Id`) that belongs to organization A, and the account
66
+ * is an app user of organization B.
67
+ *
68
+ * Unknown here means "not a mismatch": no app named, an app with no configured
69
+ * organization, or an account that is staff only. Those keep working as before.
70
+ */
71
+ function isAccountFromAnotherApp(appOrganizations, appId, account) {
72
+ if (!appId)
73
+ return false;
74
+ const expected = appOrganizations.get(appId);
75
+ if (expected === undefined)
76
+ return false;
77
+ if (!hasAppRole(account.roles))
78
+ return false;
79
+ return Number(account.organizationId) !== expected;
80
+ }
81
+ /** Error codes a client can act on, for the account rules above. */
82
+ exports.APP_ACCOUNT_ERROR_CODES = {
83
+ /** A token or session belongs to another organization's app: sign out and sign in again here. */
84
+ APP_ACCOUNT_MISMATCH: 'APP_ACCOUNT_MISMATCH',
85
+ /** A sign-in names an app and an organization that do not belong together. */
86
+ APP_ORGANIZATION_MISMATCH: 'APP_ORGANIZATION_MISMATCH',
87
+ /** An older app asked for "the" account of a number that has accounts with several organizations. */
88
+ ACCOUNT_AMBIGUOUS: 'ACCOUNT_AMBIGUOUS',
89
+ };
90
+ //# sourceMappingURL=app-account.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-account.util.js","sourceRoot":"","sources":["../../../../../src/modules/user/utils/app-account.util.ts"],"names":[],"mappings":";;;AAuBA,oCAEC;AAGD,gCAEC;AAeD,sDAmBC;AAUD,0DAUC;AApFD,0DAAmD;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,gBAAgB,GAAG,iBAAK,CAAC,WAAW,CAAC;AAElD,oGAAoG;AACpG,SAAgB,YAAY,CAAC,KAA2C;IACpE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,wBAAgB,CAAC;AACvF,CAAC;AAED,kGAAkG;AAClG,SAAgB,UAAU,CAAC,KAA2C;IAClE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,wBAAgB,CAAC,CAAC;AACpE,CAAC;AAUD;;;;GAIG;AACH,SAAgB,qBAAqB,CAAC,GAA8B;IAChE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,KAAK,GAAG,gCAAgC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,mCAAmC,CAAC,CAAC;QAC/F,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;QAC5B,MAAM,cAAc,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,+BAA+B,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,gCAAgC,QAAQ,QAAQ,cAAc,GAAG,CAAC,CAAC;QAClH,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CACnC,gBAAkC,EAClC,KAAgC,EAChC,OAAsF;IAEtF,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,QAAQ,CAAC;AACvD,CAAC;AAED,oEAAoE;AACvD,QAAA,uBAAuB,GAAG;IACnC,iGAAiG;IACjG,oBAAoB,EAAE,sBAAsB;IAC5C,8EAA8E;IAC9E,yBAAyB,EAAE,2BAA2B;IACtD,qGAAqG;IACrG,iBAAiB,EAAE,mBAAmB;CAChC,CAAC"}
@@ -0,0 +1,62 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { ArrayMaxSize, ArrayMinSize, IsArray, IsEnum, IsInt, IsISO8601, IsPositive } from "class-validator";
11
+ /** What changed about somebody's guardians - for logs and analytics; every reason means "refresh". */
12
+ export var GuardiansChangedReason;
13
+ (function (GuardiansChangedReason) {
14
+ /** A guardian was added. */
15
+ GuardiansChangedReason["ADDED"] = "ADDED";
16
+ /** A guardian was removed by the person they guard. */
17
+ GuardiansChangedReason["REMOVED"] = "REMOVED";
18
+ /** Another guardian became the primary one. */
19
+ GuardiansChangedReason["PRIMARY_CHANGED"] = "PRIMARY_CHANGED";
20
+ /** A guardian on the list by phone number proved that number in the same organization's app, and is now an app guardian. */
21
+ GuardiansChangedReason["PROMOTED"] = "PROMOTED";
22
+ /** An app guardian's account was deleted; they stay on the list by phone number. */
23
+ GuardiansChangedReason["DEMOTED"] = "DEMOTED";
24
+ /** A guardian stopped looking after one of their dependents. */
25
+ GuardiansChangedReason["DEPENDENT_REMOVED"] = "DEPENDENT_REMOVED";
26
+ })(GuardiansChangedReason || (GuardiansChangedReason = {}));
27
+ /**
28
+ * Payload of `KAFKA_TOPICS.GUARDIANS_CHANGED`: somebody's guardian list changed,
29
+ * and these people's apps should read their guardians and dependents again.
30
+ *
31
+ * Ids only - no names, numbers or relationships. The apps read the lists through
32
+ * the guardian API, which applies its own access rules.
33
+ */
34
+ export class GuardiansChangedPayloadDto {
35
+ }
36
+ __decorate([
37
+ IsInt(),
38
+ IsPositive(),
39
+ __metadata("design:type", Number)
40
+ ], GuardiansChangedPayloadDto.prototype, "organizationId", void 0);
41
+ __decorate([
42
+ IsInt(),
43
+ IsPositive(),
44
+ __metadata("design:type", Number)
45
+ ], GuardiansChangedPayloadDto.prototype, "dependentId", void 0);
46
+ __decorate([
47
+ IsArray(),
48
+ ArrayMinSize(1),
49
+ ArrayMaxSize(100),
50
+ IsInt({ each: true }),
51
+ IsPositive({ each: true }),
52
+ __metadata("design:type", Array)
53
+ ], GuardiansChangedPayloadDto.prototype, "userIds", void 0);
54
+ __decorate([
55
+ IsEnum(GuardiansChangedReason),
56
+ __metadata("design:type", String)
57
+ ], GuardiansChangedPayloadDto.prototype, "reason", void 0);
58
+ __decorate([
59
+ IsISO8601(),
60
+ __metadata("design:type", String)
61
+ ], GuardiansChangedPayloadDto.prototype, "occurredAt", void 0);
62
+ //# sourceMappingURL=guardians-changed-payload.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardians-changed-payload.dto.js","sourceRoot":"","sources":["../../../../../src/kafka/dtos/user/guardians-changed-payload.dto.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE5G,sGAAsG;AACtG,MAAM,CAAN,IAAY,sBAaX;AAbD,WAAY,sBAAsB;IAC9B,4BAA4B;IAC5B,yCAAe,CAAA;IACf,uDAAuD;IACvD,6CAAmB,CAAA;IACnB,+CAA+C;IAC/C,6DAAmC,CAAA;IACnC,4HAA4H;IAC5H,+CAAqB,CAAA;IACrB,oFAAoF;IACpF,6CAAmB,CAAA;IACnB,gEAAgE;IAChE,iEAAuC,CAAA;AAC3C,CAAC,EAbW,sBAAsB,KAAtB,sBAAsB,QAajC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,0BAA0B;CAwBtC;AApBG;IAFC,KAAK,EAAE;IACP,UAAU,EAAE;;kEACW;AAKxB;IAFC,KAAK,EAAE;IACP,UAAU,EAAE;;+DACQ;AAQrB;IALC,OAAO,EAAE;IACT,YAAY,CAAC,CAAC,CAAC;IACf,YAAY,CAAC,GAAG,CAAC;IACjB,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;;2DACR;AAGnB;IADC,MAAM,CAAC,sBAAsB,CAAC;;0DACC;AAGhC;IADC,SAAS,EAAE;;8DACQ"}
@@ -8,4 +8,5 @@ export * from './dtos/otp/create-otp-payload.dto';
8
8
  export * from './dtos/otp/otp-payload.dto';
9
9
  export * from './dtos/password/password-reset-payload.dto';
10
10
  export * from './dtos/account-deletion/account-deletion-request-payload.dto';
11
+ export * from './dtos/user/guardians-changed-payload.dto';
11
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kafka/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,6CAA6C,CAAC;AAC5D,cAAc,sCAAsC,CAAC;AACrD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,8DAA8D,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/kafka/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,6CAA6C,CAAC;AAC5D,cAAc,sCAAsC,CAAC;AACrD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,8DAA8D,CAAC;AAC7E,cAAc,2CAA2C,CAAC"}
@@ -9,6 +9,10 @@ export const KAFKA_TOPICS = {
9
9
  USER_CREATED: 'user.created',
10
10
  USER_UPDATED: 'user.updated',
11
11
  USER_DELETED: 'user.deleted',
12
+ // Somebody's guardians or dependents changed (producer: clarion-authentication;
13
+ // payload GuardiansChangedPayloadDto; consumer: clarion-notification, which
14
+ // sends each affected person a silent push so their app refreshes). Ids only.
15
+ GUARDIANS_CHANGED: 'user.guardians.changed.v1',
12
16
  // Org. ORG_CREATED is published by clarion-organization after commit
13
17
  // (payload OrganizationCreatedEvent); clarion-incident provisions the Safety
14
18
  // Alerts category from it.
@@ -1 +1 @@
1
- {"version":3,"file":"topics.js","sourceRoot":"","sources":["../../../src/kafka/topics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"topics.js","sourceRoot":"","sources":["../../../src/kafka/topics.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG;IACxB,OAAO;IACP,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,6BAA6B,EAAE,+BAA+B;IAC9D,6BAA6B,EAAE,+BAA+B;IAC9D,OAAO;IACP,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,gFAAgF;IAChF,4EAA4E;IAC5E,8EAA8E;IAC9E,iBAAiB,EAAE,2BAA2B;IAC9C,qEAAqE;IACrE,6EAA6E;IAC7E,2BAA2B;IAC3B,WAAW,EAAE,aAAa;IAC1B,WAAW,EAAE,aAAa;IAC1B,WAAW,EAAE,aAAa;IAC1B,MAAM;IACN,YAAY,EAAE,eAAe;IAC7B,aAAa,EAAE,eAAe;IAC9B,WAAW;IACX,cAAc,EAAE,gBAAgB;IAChC,WAAW;IACX,gBAAgB,EAAE,kBAAkB;IACpC,gBAAgB,EAAE,kBAAkB;IACpC,uBAAuB,EAAE,yBAAyB;IAClD,sBAAsB,EAAE,wBAAwB;IAChD,yBAAyB,EAAE,2BAA2B;IACtD,wBAAwB,EAAE,0BAA0B;IACpD,0BAA0B,EAAE,4BAA4B;IACxD,sBAAsB,EAAE,wBAAwB;IAChD,iBAAiB,EAAE,mBAAmB;IACtC,2BAA2B,EAAE,6BAA6B;IAC1D,yCAAyC,EAAE,2CAA2C;IACtF,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,6EAA6E;IAC7E,uCAAuC,EAAE,4CAA4C;IACrF,8CAA8C,EAAE,mDAAmD;IACnG,sDAAsD,EAClD,2DAA2D;IAC/D,qEAAqE;IACrE,+BAA+B;IAC/B,0CAA0C,EAAE,4DAA4D;IACxG,OAAO;IACP,oBAAoB,EAAE,sBAAsB;IAC5C,yBAAyB,EAAE,2BAA2B;IACtD,qBAAqB,EAAE,uBAAuB;IAC9C,OAAO;IACP,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,aAAa;IAC1B,OAAO;IACP,iBAAiB,EAAE,mBAAmB;IACtC,oBAAoB,EAAE,sBAAsB;IAC5C,WAAW;IACX,qBAAqB,EAAE,uBAAuB;IAC9C,uBAAuB,EAAE,yBAAyB;IAClD,qBAAqB,EAAE,uBAAuB;IAC9C,sBAAsB,EAAE,wBAAwB;IAChD,qBAAqB,EAAE,uBAAuB;IAC9C,mBAAmB,EAAE,qBAAqB;IAC1C,qBAAqB,EAAE,uBAAuB;IAC9C,oBAAoB,EAAE,sBAAsB;IAC5C,wBAAwB,EAAE,0BAA0B;IACpD,wBAAwB,EAAE,0BAA0B;IACpD,wBAAwB,EAAE,0BAA0B;IACpD,iEAAiE;IACjE,iBAAiB,EAAE,oCAAoC;IACvD,eAAe,EAAE,kCAAkC;IACnD,wBAAwB,EAAE,6BAA6B;IACvD,wBAAwB,EAAE,6BAA6B;IACvD,wBAAwB,EAAE,6BAA6B;IACvD,wEAAwE;IACxE,+DAA+D;IAC/D,yBAAyB,EAAE,uCAAuC;IAClE,yBAAyB,EAAE,uCAAuC;IAClE,yBAAyB,EAAE,uCAAuC;IAClE,wCAAwC,EACpC,sDAAsD;IAC1D,gCAAgC,EAAE,8CAA8C;IAChF,iFAAiF;IACjF,wBAAwB,EAAE,6BAA6B;IACvD,+BAA+B,EAAE,oCAAoC;IACrE,iFAAiF;IACjF,2EAA2E;IAC3E,4EAA4E;IAC5E,2EAA2E;IAC3E,iEAAiE;IACjE,sBAAsB,EAAE,2BAA2B;IACnD,sBAAsB,EAAE,2BAA2B;IACnD,uBAAuB,EAAE,4BAA4B;IACrD,6BAA6B,EAAE,kCAAkC;IACjE,+BAA+B,EAAE,oCAAoC;IACrE,8BAA8B,EAAE,mCAAmC;IACnE,+BAA+B,EAAE,oCAAoC;IACrE,4BAA4B,EAAE,iCAAiC;IAC/D,uBAAuB,EAAE,4BAA4B;IACrD,qBAAqB,EAAE,0BAA0B;IACjD,uBAAuB,EAAE,4BAA4B;IACrD,0BAA0B,EAAE,+BAA+B;IAC3D,2BAA2B,EAAE,gCAAgC;IAC7D,wBAAwB,EAAE,6BAA6B;IACvD,wBAAwB,EAAE,6BAA6B;IACvD,yBAAyB,EAAE,8BAA8B;IACzD,0BAA0B,EAAE,+BAA+B;IAC3D,oCAAoC,EAAE,yCAAyC;IAC/E,iCAAiC,EAAE,sCAAsC;IACzE,4BAA4B,EAAE,iCAAiC;IAC/D,+BAA+B,EAAE,oCAAoC;IACrE,wEAAwE;IACxE,8EAA8E;IAC9E,mDAAmD;IACnD,oBAAoB,EAAE,yBAAyB;IAC/C,sBAAsB,EAAE,2BAA2B;IACnD,kBAAkB,EAAE,uBAAuB;IAC3C,0BAA0B,EAAE,+BAA+B;IAC3D,+EAA+E;IAC/E,8DAA8D;IAC9D,iBAAiB,EAAE,6BAA6B;IAChD,4BAA4B,EAAE,wCAAwC;IACtE,mBAAmB,EAAE,+BAA+B;IACpD,uBAAuB,EAAE,mCAAmC;IAC5D,eAAe,EAAE,2BAA2B;IAC5C,2EAA2E;IAC3E,uEAAuE;IACvE,6EAA6E;IAC7E,+BAA+B;IAC/B,qCAAqC,EAAE,0CAA0C;IACjF,oBAAoB,EAAE,yBAAyB;IAC/C,8BAA8B,EAAE,mCAAmC;IACnE,0EAA0E;IAC1E,0EAA0E;IAC1E,yCAAyC,EAAE,8CAA8C;IACzF,sCAAsC,EAAE,wDAAwD;CACnG,CAAC"}
@@ -0,0 +1,38 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { ApiProperty } from '@nestjs/swagger';
11
+ import { IsInt, IsNotEmpty, IsPositive, IsString, MaxLength } from 'class-validator';
12
+ /**
13
+ * Signing out of the app: this device stops receiving the signed-out account's
14
+ * pushes (`POST /api/push-notifications/device-tokens/unregister`). Before this a
15
+ * signed-out phone kept receiving that person's SOS alerts and guardian pushes
16
+ * until somebody else signed in on it.
17
+ */
18
+ export class UnregisterDeviceTokenDto {
19
+ }
20
+ __decorate([
21
+ ApiProperty({ description: 'The FCM/APNs registration token of this device', maxLength: 4096 }),
22
+ IsString(),
23
+ IsNotEmpty(),
24
+ MaxLength(4096),
25
+ __metadata("design:type", String)
26
+ ], UnregisterDeviceTokenDto.prototype, "deviceToken", void 0);
27
+ /**
28
+ * The gateway's request to clarion-notification: the token, and the SIGNED-IN caller
29
+ * it must belong to. A token registered to anybody else is left alone.
30
+ */
31
+ export class UnregisterDeviceTokenRequestDto extends UnregisterDeviceTokenDto {
32
+ }
33
+ __decorate([
34
+ IsInt(),
35
+ IsPositive(),
36
+ __metadata("design:type", Number)
37
+ ], UnregisterDeviceTokenRequestDto.prototype, "userId", void 0);
38
+ //# sourceMappingURL=unregister-device-token.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unregister-device-token.dto.js","sourceRoot":"","sources":["../../../../../src/modules/notification/dtos/unregister-device-token.dto.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAErF;;;;;GAKG;AACH,MAAM,OAAO,wBAAwB;CAMpC;AADG;IAJC,WAAW,CAAC,EAAE,WAAW,EAAE,gDAAgD,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC/F,QAAQ,EAAE;IACV,UAAU,EAAE;IACZ,SAAS,CAAC,IAAI,CAAC;;6DACK;AAGzB;;;GAGG;AACH,MAAM,OAAO,+BAAgC,SAAQ,wBAAwB;CAI5E;AADG;IAFC,KAAK,EAAE;IACP,UAAU,EAAE;;+DACG"}
@@ -32,4 +32,6 @@ export * from './dtos/alert-acknowledgement.dto';
32
32
  // Notification Analytics (GET /admin/analytics, through the gateway's /notifications/admin/analytics)
33
33
  export * from './interfaces/notification-analytics';
34
34
  export * from './dtos/notification-analytics-query.dto';
35
+ // Signing out: the device stops receiving the account's pushes
36
+ export * from './dtos/unregister-device-token.dto';
35
37
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/notification/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAE1D,4CAA4C;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2CAA2C,CAAC;AAE1D,0CAA0C;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAEhD,kEAAkE;AAClE,cAAc,iDAAiD,CAAC;AAChE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,uCAAuC,CAAC;AACtD,cAAc,kCAAkC,CAAC;AAEjD,wFAAwF;AACxF,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,0CAA0C,CAAC;AAEzD,oHAAoH;AACpH,cAAc,kCAAkC,CAAC;AAEjD,sGAAsG;AACtG,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/notification/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yCAAyC,CAAC;AACxD,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAE1D,4CAA4C;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2CAA2C,CAAC;AAE1D,0CAA0C;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAEhD,kEAAkE;AAClE,cAAc,iDAAiD,CAAC;AAChE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,uCAAuC,CAAC;AACtD,cAAc,kCAAkC,CAAC;AAEjD,wFAAwF;AACxF,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,0CAA0C,CAAC;AAEzD,oHAAoH;AACpH,cAAc,kCAAkC,CAAC;AAEjD,sGAAsG;AACtG,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC;AAExD,+DAA+D;AAC/D,cAAc,oCAAoC,CAAC"}
@@ -13,7 +13,7 @@ export class GuardianIdentifierDto {
13
13
  }
14
14
  __decorate([
15
15
  ApiProperty({
16
- description: 'Phone number for external guardian',
16
+ description: 'Phone number of an external guardian (older apps). Prefer relationshipId, which names either kind.',
17
17
  example: '+1234567890',
18
18
  required: false,
19
19
  type: 'string'
@@ -24,7 +24,7 @@ __decorate([
24
24
  ], GuardianIdentifierDto.prototype, "phoneNumber", void 0);
25
25
  __decorate([
26
26
  ApiProperty({
27
- description: 'Relationship ID for system guardian',
27
+ description: 'The guardian entry id - `id` of an app-user guardian relation or of an external guardian (since grm-shared-library 1.1.248)',
28
28
  example: 789,
29
29
  required: false,
30
30
  type: 'number'
@@ -1 +1 @@
1
- {"version":3,"file":"guardian-identifier.dto.js","sourceRoot":"","sources":["../../../../../src/modules/user/dtos/guardian-identifier.dto.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAc,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7E,MAAM,OAAO,qBAAqB;CAoBjC;AAXG;IARC,WAAW,CAAC;QACT,WAAW,EAAE,oCAAoC;QACjD,OAAO,EAAE,aAAa;QACtB,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,QAAQ;KACjB,CAAC;IACD,QAAQ,EAAE;IACV,UAAU,EAAE;;0DACQ;AAUrB;IARC,WAAW,CAAC;QACT,WAAW,EAAE,qCAAqC;QAClD,OAAO,EAAE,GAAG;QACZ,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,QAAQ;KACjB,CAAC;IACD,QAAQ,EAAE;IACV,UAAU,EAAE;;6DACW"}
1
+ {"version":3,"file":"guardian-identifier.dto.js","sourceRoot":"","sources":["../../../../../src/modules/user/dtos/guardian-identifier.dto.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAc,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7E,MAAM,OAAO,qBAAqB;CAoBjC;AAXG;IARC,WAAW,CAAC;QACT,WAAW,EAAE,oGAAoG;QACjH,OAAO,EAAE,aAAa;QACtB,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,QAAQ;KACjB,CAAC;IACD,QAAQ,EAAE;IACV,UAAU,EAAE;;0DACQ;AAUrB;IARC,WAAW,CAAC;QACT,WAAW,EAAE,6HAA6H;QAC1I,OAAO,EAAE,GAAG;QACZ,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,QAAQ;KACjB,CAAC;IACD,QAAQ,EAAE;IACV,UAAU,EAAE;;6DACW"}
@@ -16,4 +16,5 @@ export * from './interfaces/guardian';
16
16
  export * from './interfaces/guardian-relation';
17
17
  export * from './interfaces/guardians-response';
18
18
  export * from './interfaces/account-analytics';
19
+ export * from './utils/app-account.util';
19
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/user/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AACpD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,wCAAwC,CAAC;AAEvD,cAAc,0BAA0B,CAAC;AACzC,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AAEtD,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/modules/user/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AACpD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,wCAAwC,CAAC;AAEvD,cAAc,0BAA0B,CAAC;AACzC,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AAEtD,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAE/C,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { Roles } from '../../role/enums/role.enum';
2
+ /**
3
+ * App accounts and staff accounts.
4
+ *
5
+ * Each brand's mobile app (G4S Kenya, GeoSHIELD, SGA Security, ...) is its own
6
+ * product for one organization's customers, so an account made in one app is an
7
+ * account with that organization only. Signing in to another brand's app means
8
+ * registering with that brand. One person may therefore hold several app
9
+ * accounts - one per organization - with the same phone number and e-mail.
10
+ *
11
+ * Staff (Super-Admin, organization and control-centre staff, responders,
12
+ * corporate-client admins) keep one platform-wide account each: their e-mail and
13
+ * phone number stay unique across the whole platform.
14
+ *
15
+ * An APP ACCOUNT is one whose only role is Mobile-User. That is the same rule the
16
+ * database's unique indexes use (`roles = '{Mobile-User}'`), so code and schema
17
+ * can never disagree about which kind an account is. An account holding
18
+ * Mobile-User beside a staff role is a staff account that also uses an app.
19
+ */
20
+ export const APP_ACCOUNT_ROLE = Roles.MOBILE_USER;
21
+ /** An account whose only role is Mobile-User: unique within its organization, not platform-wide. */
22
+ export function isAppAccount(roles) {
23
+ return Array.isArray(roles) && roles.length === 1 && roles[0] === APP_ACCOUNT_ROLE;
24
+ }
25
+ /** Holds the Mobile-User role, alone or beside staff roles: someone who can use a brand's app. */
26
+ export function hasAppRole(roles) {
27
+ return Array.isArray(roles) && roles.includes(APP_ACCOUNT_ROLE);
28
+ }
29
+ /**
30
+ * Parses `APP_ORGANIZATIONS`. Blank means "none configured". A malformed entry
31
+ * throws: a typo here would let an app sign people in to the wrong organization,
32
+ * so it must stop the service at boot rather than be skipped.
33
+ */
34
+ export function parseAppOrganizations(raw) {
35
+ const map = new Map();
36
+ for (const entry of String(raw !== null && raw !== void 0 ? raw : '').split(',')) {
37
+ const trimmed = entry.trim();
38
+ if (!trimmed)
39
+ continue;
40
+ const match = /^([A-Za-z0-9_-]+)\s*:\s*(\d+)$/.exec(trimmed);
41
+ if (!match)
42
+ throw new Error(`APP_ORGANIZATIONS: "${trimmed}" is not <appId>:<organizationId>`);
43
+ const [, appId, id] = match;
44
+ const organizationId = Number(id);
45
+ if (!Number.isSafeInteger(organizationId) || organizationId <= 0) {
46
+ throw new Error(`APP_ORGANIZATIONS: "${trimmed}" names no valid organization`);
47
+ }
48
+ const existing = map.get(appId);
49
+ if (existing !== undefined && existing !== organizationId) {
50
+ throw new Error(`APP_ORGANIZATIONS: ${appId} is given two organizations (${existing} and ${organizationId})`);
51
+ }
52
+ map.set(appId, organizationId);
53
+ }
54
+ return map;
55
+ }
56
+ /**
57
+ * Whether a signed-in account is being used from another organization's app: the
58
+ * request names an app (`X-App-Id`) that belongs to organization A, and the account
59
+ * is an app user of organization B.
60
+ *
61
+ * Unknown here means "not a mismatch": no app named, an app with no configured
62
+ * organization, or an account that is staff only. Those keep working as before.
63
+ */
64
+ export function isAccountFromAnotherApp(appOrganizations, appId, account) {
65
+ if (!appId)
66
+ return false;
67
+ const expected = appOrganizations.get(appId);
68
+ if (expected === undefined)
69
+ return false;
70
+ if (!hasAppRole(account.roles))
71
+ return false;
72
+ return Number(account.organizationId) !== expected;
73
+ }
74
+ /** Error codes a client can act on, for the account rules above. */
75
+ export const APP_ACCOUNT_ERROR_CODES = {
76
+ /** A token or session belongs to another organization's app: sign out and sign in again here. */
77
+ APP_ACCOUNT_MISMATCH: 'APP_ACCOUNT_MISMATCH',
78
+ /** A sign-in names an app and an organization that do not belong together. */
79
+ APP_ORGANIZATION_MISMATCH: 'APP_ORGANIZATION_MISMATCH',
80
+ /** An older app asked for "the" account of a number that has accounts with several organizations. */
81
+ ACCOUNT_AMBIGUOUS: 'ACCOUNT_AMBIGUOUS',
82
+ };
83
+ //# sourceMappingURL=app-account.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-account.util.js","sourceRoot":"","sources":["../../../../../src/modules/user/utils/app-account.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAEnD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC;AAElD,oGAAoG;AACpG,MAAM,UAAU,YAAY,CAAC,KAA2C;IACpE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAC;AACvF,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,UAAU,CAAC,KAA2C;IAClE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACpE,CAAC;AAUD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAA8B;IAChE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,KAAK,GAAG,gCAAgC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,mCAAmC,CAAC,CAAC;QAC/F,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;QAC5B,MAAM,cAAc,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,+BAA+B,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,gCAAgC,QAAQ,QAAQ,cAAc,GAAG,CAAC,CAAC;QAClH,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACnC,gBAAkC,EAClC,KAAgC,EAChC,OAAsF;IAEtF,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,QAAQ,CAAC;AACvD,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACnC,iGAAiG;IACjG,oBAAoB,EAAE,sBAAsB;IAC5C,8EAA8E;IAC9E,yBAAyB,EAAE,2BAA2B;IACtD,qGAAqG;IACrG,iBAAiB,EAAE,mBAAmB;CAChC,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** What changed about somebody's guardians - for logs and analytics; every reason means "refresh". */
2
+ export declare enum GuardiansChangedReason {
3
+ /** A guardian was added. */
4
+ ADDED = "ADDED",
5
+ /** A guardian was removed by the person they guard. */
6
+ REMOVED = "REMOVED",
7
+ /** Another guardian became the primary one. */
8
+ PRIMARY_CHANGED = "PRIMARY_CHANGED",
9
+ /** A guardian on the list by phone number proved that number in the same organization's app, and is now an app guardian. */
10
+ PROMOTED = "PROMOTED",
11
+ /** An app guardian's account was deleted; they stay on the list by phone number. */
12
+ DEMOTED = "DEMOTED",
13
+ /** A guardian stopped looking after one of their dependents. */
14
+ DEPENDENT_REMOVED = "DEPENDENT_REMOVED"
15
+ }
16
+ /**
17
+ * Payload of `KAFKA_TOPICS.GUARDIANS_CHANGED`: somebody's guardian list changed,
18
+ * and these people's apps should read their guardians and dependents again.
19
+ *
20
+ * Ids only - no names, numbers or relationships. The apps read the lists through
21
+ * the guardian API, which applies its own access rules.
22
+ */
23
+ export declare class GuardiansChangedPayloadDto {
24
+ /** The organization whose app the people use. Pushes go only to devices of this organization. */
25
+ organizationId: number;
26
+ /** Whose guardian list changed. */
27
+ dependentId: number;
28
+ /** Every app user whose guardians or dependents changed: the dependent and any app guardian involved. */
29
+ userIds: number[];
30
+ reason: GuardiansChangedReason;
31
+ occurredAt: string;
32
+ }
@@ -8,3 +8,4 @@ export * from './dtos/otp/create-otp-payload.dto';
8
8
  export * from './dtos/otp/otp-payload.dto';
9
9
  export * from './dtos/password/password-reset-payload.dto';
10
10
  export * from './dtos/account-deletion/account-deletion-request-payload.dto';
11
+ export * from './dtos/user/guardians-changed-payload.dto';
@@ -7,6 +7,7 @@ export declare const KAFKA_TOPICS: {
7
7
  USER_CREATED: string;
8
8
  USER_UPDATED: string;
9
9
  USER_DELETED: string;
10
+ GUARDIANS_CHANGED: string;
10
11
  ORG_CREATED: string;
11
12
  ORG_UPDATED: string;
12
13
  ORG_DELETED: string;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Signing out of the app: this device stops receiving the signed-out account's
3
+ * pushes (`POST /api/push-notifications/device-tokens/unregister`). Before this a
4
+ * signed-out phone kept receiving that person's SOS alerts and guardian pushes
5
+ * until somebody else signed in on it.
6
+ */
7
+ export declare class UnregisterDeviceTokenDto {
8
+ deviceToken: string;
9
+ }
10
+ /**
11
+ * The gateway's request to clarion-notification: the token, and the SIGNED-IN caller
12
+ * it must belong to. A token registered to anybody else is left alone.
13
+ */
14
+ export declare class UnregisterDeviceTokenRequestDto extends UnregisterDeviceTokenDto {
15
+ userId: number;
16
+ }
17
+ export interface UnregisterDeviceTokenResult {
18
+ /** False when the token is unknown, already inactive, or another account's. */
19
+ deactivated: boolean;
20
+ }
@@ -25,3 +25,4 @@ export * from './interfaces/billing-notification-result';
25
25
  export * from './dtos/alert-acknowledgement.dto';
26
26
  export * from './interfaces/notification-analytics';
27
27
  export * from './dtos/notification-analytics-query.dto';
28
+ export * from './dtos/unregister-device-token.dto';
@@ -16,3 +16,4 @@ export * from './interfaces/guardian';
16
16
  export * from './interfaces/guardian-relation';
17
17
  export * from './interfaces/guardians-response';
18
18
  export * from './interfaces/account-analytics';
19
+ export * from './utils/app-account.util';
@@ -1,5 +1,12 @@
1
1
  import { GuardianRelationship } from "../enums/guardian-relationship.enum";
2
2
  export interface Guardian {
3
+ /**
4
+ * The guardian entry's own id. External and app-user guardians share one table
5
+ * and one id space, so either kind can be removed or made primary by it
6
+ * (`GuardianIdentifierDto.relationshipId`). Absent only from responses of
7
+ * clarion-authentication builds older than grm-shared-library 1.1.248.
8
+ */
9
+ id?: number;
3
10
  userId?: number;
4
11
  name: string;
5
12
  phoneNumber: string;
@@ -0,0 +1,59 @@
1
+ import { Roles } from '../../role/enums/role.enum';
2
+ /**
3
+ * App accounts and staff accounts.
4
+ *
5
+ * Each brand's mobile app (G4S Kenya, GeoSHIELD, SGA Security, ...) is its own
6
+ * product for one organization's customers, so an account made in one app is an
7
+ * account with that organization only. Signing in to another brand's app means
8
+ * registering with that brand. One person may therefore hold several app
9
+ * accounts - one per organization - with the same phone number and e-mail.
10
+ *
11
+ * Staff (Super-Admin, organization and control-centre staff, responders,
12
+ * corporate-client admins) keep one platform-wide account each: their e-mail and
13
+ * phone number stay unique across the whole platform.
14
+ *
15
+ * An APP ACCOUNT is one whose only role is Mobile-User. That is the same rule the
16
+ * database's unique indexes use (`roles = '{Mobile-User}'`), so code and schema
17
+ * can never disagree about which kind an account is. An account holding
18
+ * Mobile-User beside a staff role is a staff account that also uses an app.
19
+ */
20
+ export declare const APP_ACCOUNT_ROLE = Roles.MOBILE_USER;
21
+ /** An account whose only role is Mobile-User: unique within its organization, not platform-wide. */
22
+ export declare function isAppAccount(roles: readonly string[] | null | undefined): boolean;
23
+ /** Holds the Mobile-User role, alone or beside staff roles: someone who can use a brand's app. */
24
+ export declare function hasAppRole(roles: readonly string[] | null | undefined): boolean;
25
+ /**
26
+ * Which organization each brand's app belongs to, as configured in
27
+ * `APP_ORGANIZATIONS` - for example `GardaWorld:48,G4S:49,SGA:51`. The ids differ
28
+ * per environment (Dev has its own organizations), which is why this is
29
+ * configuration and not code.
30
+ */
31
+ export type AppOrganizations = ReadonlyMap<string, number>;
32
+ /**
33
+ * Parses `APP_ORGANIZATIONS`. Blank means "none configured". A malformed entry
34
+ * throws: a typo here would let an app sign people in to the wrong organization,
35
+ * so it must stop the service at boot rather than be skipped.
36
+ */
37
+ export declare function parseAppOrganizations(raw: string | null | undefined): AppOrganizations;
38
+ /**
39
+ * Whether a signed-in account is being used from another organization's app: the
40
+ * request names an app (`X-App-Id`) that belongs to organization A, and the account
41
+ * is an app user of organization B.
42
+ *
43
+ * Unknown here means "not a mismatch": no app named, an app with no configured
44
+ * organization, or an account that is staff only. Those keep working as before.
45
+ */
46
+ export declare function isAccountFromAnotherApp(appOrganizations: AppOrganizations, appId: string | null | undefined, account: {
47
+ roles?: readonly string[] | null;
48
+ organizationId?: number | string | null;
49
+ }): boolean;
50
+ /** Error codes a client can act on, for the account rules above. */
51
+ export declare const APP_ACCOUNT_ERROR_CODES: {
52
+ /** A token or session belongs to another organization's app: sign out and sign in again here. */
53
+ readonly APP_ACCOUNT_MISMATCH: "APP_ACCOUNT_MISMATCH";
54
+ /** A sign-in names an app and an organization that do not belong together. */
55
+ readonly APP_ORGANIZATION_MISMATCH: "APP_ORGANIZATION_MISMATCH";
56
+ /** An older app asked for "the" account of a number that has accounts with several organizations. */
57
+ readonly ACCOUNT_AMBIGUOUS: "ACCOUNT_AMBIGUOUS";
58
+ };
59
+ export type AppAccountErrorCode = typeof APP_ACCOUNT_ERROR_CODES[keyof typeof APP_ACCOUNT_ERROR_CODES];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grm-shared-library",
3
- "version": "1.1.247",
3
+ "version": "1.1.249",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -45,6 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@nestjs/common": "^11.0.0",
48
+ "@nestjs/config": "^4.0.0",
48
49
  "@nestjs/core": "^11.0.0",
49
50
  "@nestjs/mapped-types": "^2.0.6",
50
51
  "@nestjs/microservices": "^11.0.0",
@@ -57,16 +58,15 @@
57
58
  "grm-shared-library": "^1.1.101",
58
59
  "libphonenumber-js": "^1.13.8",
59
60
  "rxjs": "^7.8.2",
60
- "swagger-ui-express": "^5.0.1",
61
- "@nestjs/config": "^4.0.0"
61
+ "swagger-ui-express": "^5.0.1"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "@nestjs/common": "^11.0.0",
65
+ "@nestjs/config": "^4.0.0",
65
66
  "@nestjs/core": "^11.0.0",
66
67
  "@nestjs/microservices": "^11.0.0",
67
68
  "@sentry/node": "^8.0.0",
68
69
  "class-transformer": "^0.5.0",
69
- "class-validator": "^0.14.0",
70
- "@nestjs/config": "^4.0.0"
70
+ "class-validator": "^0.14.0"
71
71
  }
72
72
  }