@raytio/core 11.0.0 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/README.md +100 -1
  3. package/dist/crypto/getAADecryptor.js +32 -4
  4. package/dist/schema/expandSchema/__tests__/addLoadingTimes.test.d.ts +1 -0
  5. package/dist/schema/expandSchema/__tests__/addLoadingTimes.test.js +24 -0
  6. package/dist/schema/expandSchema/__tests__/expandSchema.test.d.ts +1 -0
  7. package/dist/schema/expandSchema/__tests__/expandSchema.test.js +96 -0
  8. package/dist/schema/expandSchema/__tests__/i18n.test.d.ts +1 -0
  9. package/dist/schema/expandSchema/__tests__/i18n.test.js +32 -0
  10. package/dist/schema/expandSchema/__tests__/maybeUseI18n.test.d.ts +1 -0
  11. package/dist/schema/expandSchema/__tests__/maybeUseI18n.test.js +98 -0
  12. package/dist/schema/expandSchema/__tests__/processSchema.test.d.ts +1 -0
  13. package/dist/schema/expandSchema/__tests__/processSchema.test.js +326 -0
  14. package/dist/schema/expandSchema/__tests__/sortSchemaProperties.test.d.ts +1 -0
  15. package/dist/schema/expandSchema/__tests__/sortSchemaProperties.test.js +182 -0
  16. package/dist/schema/expandSchema/__tests__/util.test.d.ts +1 -0
  17. package/dist/schema/expandSchema/__tests__/util.test.js +19 -0
  18. package/dist/schema/expandSchema/addLoadingTimes.d.ts +2 -0
  19. package/dist/schema/expandSchema/addLoadingTimes.js +12 -0
  20. package/dist/schema/expandSchema/constants.d.ts +2 -0
  21. package/dist/schema/expandSchema/constants.js +11 -0
  22. package/dist/schema/expandSchema/expandSchema.d.ts +7 -0
  23. package/dist/schema/expandSchema/expandSchema.js +19 -0
  24. package/dist/schema/expandSchema/i18n.d.ts +5 -0
  25. package/dist/schema/expandSchema/i18n.js +20 -0
  26. package/dist/schema/expandSchema/index.d.ts +3 -0
  27. package/dist/schema/expandSchema/index.js +21 -0
  28. package/dist/schema/expandSchema/maybeUseI18n.d.ts +2 -0
  29. package/dist/schema/expandSchema/maybeUseI18n.js +40 -0
  30. package/dist/schema/expandSchema/processSchema.d.ts +3 -0
  31. package/dist/schema/expandSchema/processSchema.js +94 -0
  32. package/dist/schema/expandSchema/removePrivateFields.d.ts +121 -0
  33. package/dist/schema/expandSchema/removePrivateFields.js +15 -0
  34. package/dist/schema/expandSchema/sortSchemaProperties.d.ts +21 -0
  35. package/dist/schema/expandSchema/sortSchemaProperties.js +40 -0
  36. package/dist/schema/expandSchema/unwrapSchema.d.ts +6 -0
  37. package/dist/schema/expandSchema/unwrapSchema.js +7 -0
  38. package/dist/schema/expandSchema/util.d.ts +6 -0
  39. package/dist/schema/expandSchema/util.js +15 -0
  40. package/dist/schema/index.d.ts +1 -0
  41. package/dist/schema/index.js +1 -0
  42. package/dist/testHelpers.d.ts +9 -0
  43. package/dist/testHelpers.js +9 -0
  44. package/dist/verifications/getPOVerification.js +6 -2
  45. package/dist/verifications/getVerifiedBy.js +6 -1
  46. package/dist/verifications/safeHarbour.d.ts +1 -1
  47. package/dist/verifications/safeHarbour.js +4 -11
  48. package/dist/verifications/verifyCheck/__tests__/getOwnRealVerifications.test.js +72 -7
  49. package/dist/verifications/verifyCheck/getOwnRealVerifications.js +3 -1
  50. package/dist/verifications/verifyCheck/operations/__tests__/checkOwnVerification.test.js +45 -5
  51. package/dist/verifications/verifyCheck/operations/__tests__/sampleBundle.json +1 -0
  52. package/dist/verifications/verifyCheck/operations/checkOwnVerification.d.ts +3 -2
  53. package/dist/verifications/verifyCheck/operations/checkOwnVerification.js +15 -8
  54. package/package.json +5 -5
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.maybeUseI18n = void 0;
15
+ const ramda_1 = require("ramda");
16
+ const i18n_1 = require("./i18n");
17
+ const getGroupNames = (0, ramda_1.pipe)(ramda_1.toPairs,
18
+ // @ts-expect-error
19
+ (0, ramda_1.filter)(([key]) => key.startsWith("group:")),
20
+ // @ts-expect-error
21
+ (0, ramda_1.map)(([key, value]) => [key.replace("group:", ""), value.title]), ramda_1.fromPairs);
22
+ const maybeUseI18n = (schema, userLocales) => {
23
+ var _a;
24
+ if (!schema.i18n)
25
+ return schema;
26
+ // try to find an exact match in schema.i18n. The fallback: if the schema
27
+ // only has en-nz, but the user speaks en-US, then use en-nz.
28
+ const localeToUse = (0, i18n_1.findSuitableLocale)(Object.keys(schema.i18n), userLocales);
29
+ // the schema has an i18n property, but it doesn't include a lang that the user speaks
30
+ if (!localeToUse)
31
+ return schema;
32
+ const _b = schema.i18n[localeToUse], { $schema } = _b, translations = __rest(_b, ["$schema"]);
33
+ return Object.assign(Object.assign(Object.assign(Object.assign({}, schema), { clientLocale: localeToUse }), $schema), { group_title: schema.schema_group &&
34
+ (((_a = translations[schema.schema_group]) === null || _a === void 0 ? void 0 : _a.title_plural) || schema.schema_group),
35
+ // add a `groupNames` property to the schema
36
+ groupNames: getGroupNames(translations),
37
+ // maybe apply translations per field
38
+ properties: (0, ramda_1.mapObjIndexed)((field, fieldName) => (Object.assign(Object.assign({}, field), translations[fieldName])), schema.properties) });
39
+ };
40
+ exports.maybeUseI18n = maybeUseI18n;
@@ -0,0 +1,3 @@
1
+ import { Schema, WrappedSchema } from "@raytio/types";
2
+ import type { unwrapSchema } from "./unwrapSchema";
3
+ export declare const processSchema: (schema: ReturnType<typeof unwrapSchema>, allUnexpandedSchemas: WrappedSchema[]) => Schema;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processSchema = void 0;
4
+ const ramda_1 = require("ramda");
5
+ const constants_1 = require("./constants");
6
+ const sortSchemaProperties_1 = require("./sortSchemaProperties");
7
+ const util_1 = require("./util");
8
+ const convertIfEnum = (0, ramda_1.mapObjIndexed)(y => Object.values(y)[0]);
9
+ const processSchema = (schema, allUnexpandedSchemas) => {
10
+ var _a, _b, _c, _d, _e, _f, _g;
11
+ const expandField = (property, key) => {
12
+ var _a, _b;
13
+ if (!property.allOf)
14
+ return Object.assign(Object.assign({}, property), { $prop: key });
15
+ // this property references another schema
16
+ const [{ $ref }, custom] = property.allOf;
17
+ if (!$ref)
18
+ throw new Error("allOf missing $ref");
19
+ const subSchemaName = (0, sortSchemaProperties_1.getNidFromUrn)((_a = schema.definitions) === null || _a === void 0 ? void 0 : _a[$ref.split("/")[2]].$ref);
20
+ if (!subSchemaName)
21
+ throw new Error("Invalid schema");
22
+ const subSchema = (_b = allUnexpandedSchemas.find(s => s.schema_name === subSchemaName)) === null || _b === void 0 ? void 0 : _b.schema;
23
+ if (!subSchema) {
24
+ throw new Error(`Could not resolve subschema '${subSchemaName}'`);
25
+ }
26
+ return (0, ramda_1.pipe)((0, ramda_1.dissoc)("properties"), // subSchema don't have properties so remove
27
+ (0, ramda_1.mergeWith)((main, sub) => {
28
+ // merge custom props in; concatting arrays, but picking
29
+ // the main value only for strings.
30
+ if (typeof main === "string")
31
+ return main;
32
+ return [...main, ...sub];
33
+ }, custom), (f) => (Object.assign(Object.assign({}, f), { $ref: subSchemaName })), // add $ref to the subSchema
34
+ // add $ref to the subSchema
35
+ field => (Object.assign(Object.assign({}, field), { $prop: key })))(subSchema);
36
+ };
37
+ const exandedProps = (0, ramda_1.mapObjIndexed)(expandField, schema.properties);
38
+ const allOfRequired = [];
39
+ const globallyReferencedSubSchema = (_b = (_a = schema.allOf) === null || _a === void 0 ? void 0 : _a.reduce((ac, { $ref }) => {
40
+ var _a, _b;
41
+ // TODO: should this block of code re-use `expandField`?
42
+ if (!$ref)
43
+ return ac; // this allOf entry is not a reference
44
+ const subSchemaName = (0, sortSchemaProperties_1.getNidFromUrn)((_a = schema.definitions) === null || _a === void 0 ? void 0 : _a[$ref.split("/")[2]].$ref);
45
+ if (!subSchemaName)
46
+ throw new Error("Invalid schema");
47
+ const subSchema = (_b = allUnexpandedSchemas.find(s => s.schema_name === subSchemaName)) === null || _b === void 0 ? void 0 : _b.schema;
48
+ if (!subSchema) {
49
+ throw new Error(`Could not resolve subschema '${subSchemaName}'`);
50
+ }
51
+ if (subSchema.required) {
52
+ // eslint-disable-next-line fp/no-mutating-methods
53
+ allOfRequired.push(...subSchema.required);
54
+ }
55
+ return Object.assign(Object.assign({}, ac), (0, ramda_1.mapObjIndexed)((field, fieldName) => (Object.assign(Object.assign({}, field), { $prop: fieldName })), subSchema.properties));
56
+ }, {})) !== null && _b !== void 0 ? _b : {};
57
+ // IF properties THEN required
58
+ const conditionallyRequired = ((_c = schema.allOf) === null || _c === void 0 ? void 0 : _c.filter(x => { var _a, _b; return ((_a = x.if) === null || _a === void 0 ? void 0 : _a.properties) && ((_b = x.then) === null || _b === void 0 ? void 0 : _b.required); }).flatMap(x => x.then.required.map(field => ({
59
+ field: field,
60
+ if: convertIfEnum(x.if.properties),
61
+ })))) || [];
62
+ // IF properties THEN properties
63
+ const conditionalProperties = ((_d = schema.allOf) === null || _d === void 0 ? void 0 : _d.filter(x => { var _a, _b; return ((_a = x.if) === null || _a === void 0 ? void 0 : _a.properties) && ((_b = x.then) === null || _b === void 0 ? void 0 : _b.properties); }).reduce((ac, ifThen) => {
64
+ const props = Object.fromEntries(Object.entries(ifThen.then.properties).map(([k, v]) => {
65
+ const iff = convertIfEnum(ifThen.if.properties);
66
+ return [
67
+ `${k} <=> ${(0, util_1.getConditionId)(iff)}`,
68
+ Object.assign(Object.assign({}, expandField(v, k)), { if: iff, $prop: k }),
69
+ ];
70
+ }));
71
+ return Object.assign(Object.assign({}, ac), props);
72
+ }, {})) || {};
73
+ // IF properties THEN verifiable
74
+ const conditionallyVerifiable = ((_e = schema.allOf) === null || _e === void 0 ? void 0 : _e.filter(x => { var _a, _b; return ((_a = x.if) === null || _a === void 0 ? void 0 : _a.properties) && ((_b = x.then) === null || _b === void 0 ? void 0 : _b.verified_fields); }).flatMap(x => x.then.verified_fields.map(field => ({
75
+ field: field,
76
+ if: convertIfEnum(x.if.properties),
77
+ })))) || [];
78
+ const verifiedFields = (0, ramda_1.uniq)([
79
+ ...(schema.verified_fields || []),
80
+ ...conditionallyVerifiable,
81
+ ]);
82
+ const shouldBeConditionallyVerified = (_f = schema.allOf) === null || _f === void 0 ? void 0 : _f.some(x => { var _a, _b; return (_b = (_a = x.then) === null || _a === void 0 ? void 0 : _a.tags) === null || _b === void 0 ? void 0 : _b.includes("action:verify"); });
83
+ return Object.assign(Object.assign({}, schema), { properties: Object.assign(Object.assign(Object.assign({}, exandedProps), globallyReferencedSubSchema), conditionalProperties), required: (0, ramda_1.uniq)([
84
+ ...(schema.required || []),
85
+ ...allOfRequired,
86
+ ...conditionallyRequired,
87
+ ]),
88
+ // important that it's undefined instead of empty array so that it's falsy
89
+ verified_fields: verifiedFields.length ? verifiedFields : undefined, tags: (0, ramda_1.uniq)([
90
+ ...(schema.tags || []),
91
+ ...(shouldBeConditionallyVerified ? ["action:verify"] : []),
92
+ ]), isProfileSchema: !constants_1.TAG_DENYLIST.some(tag => { var _a; return (_a = schema.tags) === null || _a === void 0 ? void 0 : _a.includes(tag); }) && !!schema.title, isSpSchema: ((_g = schema.tags) === null || _g === void 0 ? void 0 : _g.includes("type:service_provider")) || false });
93
+ };
94
+ exports.processSchema = processSchema;
@@ -0,0 +1,121 @@
1
+ import { Schema } from "@raytio/types";
2
+ export declare const removePrivateFields: (schema: Schema) => {
3
+ properties: Record<string, Omit<import("@raytio/types").SchemaField, "$id" | "allOf" | "$schema" | "definitions">>;
4
+ title: string;
5
+ description: string;
6
+ description_decorator?: "md" | undefined;
7
+ schema_type?: import("@raytio/types").SchemaType | undefined;
8
+ title_plural?: string | undefined;
9
+ schema_group?: string | undefined;
10
+ tags?: import("@raytio/types").SchemaTag[] | undefined;
11
+ i18n?: {
12
+ [locale: string]: {
13
+ [fieldNameOrGroupName: string]: import("@raytio/types").ServerSchemaField & {
14
+ title_plural?: string | undefined;
15
+ };
16
+ $schema: {
17
+ title: string;
18
+ title_plural?: string | undefined;
19
+ description?: string | undefined;
20
+ };
21
+ $loading_extract: {
22
+ title: string;
23
+ };
24
+ $loading_verify: {
25
+ title: string;
26
+ };
27
+ $loading_save: {
28
+ title: string;
29
+ };
30
+ $loading_update: {
31
+ title: string;
32
+ };
33
+ $loading_upload: {
34
+ title: string;
35
+ };
36
+ $loading_create_sub_obj: {
37
+ title: string;
38
+ };
39
+ $loading_permission: {
40
+ title: string;
41
+ };
42
+ $loading_link_to_person: {
43
+ title: string;
44
+ };
45
+ $loading_delete_pending_ver: {
46
+ title: string;
47
+ };
48
+ $loading_pending_ver_resubmit: {
49
+ title: string;
50
+ };
51
+ $loading_long_verification_message: {
52
+ title?: string | undefined;
53
+ description?: string | undefined;
54
+ };
55
+ };
56
+ } | undefined;
57
+ relationships?: {
58
+ relationship_name: string;
59
+ direction: "from";
60
+ type: string;
61
+ required_relationship?: boolean | undefined;
62
+ oneOf?: string[] | undefined;
63
+ anyOf?: string[] | undefined;
64
+ multiple?: boolean | undefined;
65
+ properties?: {
66
+ [fieldName: string]: import("@raytio/types").SchemaField;
67
+ } | undefined;
68
+ required?: string[] | undefined;
69
+ }[] | undefined;
70
+ display?: {
71
+ head_main?: {
72
+ fields: string[];
73
+ format?: string | undefined;
74
+ } | undefined;
75
+ head_sub?: {
76
+ fields: string[];
77
+ format?: string | undefined;
78
+ } | undefined;
79
+ expand?: {
80
+ fields: string[];
81
+ label: string;
82
+ }[] | undefined;
83
+ } | undefined;
84
+ onboard_properties?: {
85
+ profile_objects?: {
86
+ schema_name: string;
87
+ properties: Record<string, unknown>;
88
+ }[] | undefined;
89
+ relationships?: {
90
+ from: string;
91
+ to: string;
92
+ type: string;
93
+ properties?: Record<string, string> | undefined;
94
+ }[] | undefined;
95
+ organizations?: {
96
+ properties: import("@raytio/types").Organization;
97
+ access_applications?: {
98
+ properties: Omit<import("@raytio/types").AA, "org_id">;
99
+ links?: {
100
+ description: string;
101
+ wizardConfig: Omit<import("@raytio/types").WizardConfig, "a_id">;
102
+ }[] | undefined;
103
+ }[] | undefined;
104
+ }[] | undefined;
105
+ return_to?: string | undefined;
106
+ } | undefined;
107
+ name: string;
108
+ type?: import("@raytio/types").DataTypes | undefined;
109
+ group_title?: string | undefined;
110
+ verified_fields?: (string | import("@raytio/types").ConditionallyRequired)[] | undefined;
111
+ required?: (string | import("@raytio/types").ConditionallyRequired)[] | undefined;
112
+ wasExpandedByClient?: boolean | undefined;
113
+ start_date?: string | undefined;
114
+ end_date?: string | undefined;
115
+ groupNames?: Record<string, string> | undefined;
116
+ clientLocale?: string | undefined;
117
+ version: string;
118
+ timing?: Record<"extract" | "live_person" | "verify_pending_delay", number> | undefined;
119
+ isProfileSchema?: boolean | undefined;
120
+ isSpSchema?: boolean | undefined;
121
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removePrivateFields = void 0;
4
+ const ramda_1 = require("ramda");
5
+ /** we don't expose these to the rest of the client to avoid confusion or misusing them */
6
+ const PRIVATE_FIELDS = [
7
+ "$id",
8
+ "$schema",
9
+ "definitions",
10
+ "allOf",
11
+ ];
12
+ const removePrivateFields = (schema) => (Object.assign(Object.assign({}, (0, ramda_1.omit)(PRIVATE_FIELDS, schema)), {
13
+ // and from each field in `properties`
14
+ properties: (0, ramda_1.mapObjIndexed)((0, ramda_1.omit)(PRIVATE_FIELDS), schema.properties) }));
15
+ exports.removePrivateFields = removePrivateFields;
@@ -0,0 +1,21 @@
1
+ import { NId, SchemaField, Urn } from "@raytio/types";
2
+ /** two overloads - if you provide undefined, you might get undefined back */
3
+ export declare const getNidFromUrn: {
4
+ (urn: Urn): NId;
5
+ (urn: Urn | undefined): NId | undefined;
6
+ };
7
+ type Key = string;
8
+ type Tag = string;
9
+ type Section = {
10
+ title: Tag;
11
+ items: SchemaField[];
12
+ };
13
+ /** @ignore */
14
+ export declare const NO_TAG = "-notag-common";
15
+ /**
16
+ * Schema properties are an object, so they need to be converted into an
17
+ * array, grouped by the group tag, and then sorted based on the `priority`
18
+ * attribute within their group.
19
+ */
20
+ export declare function sortSchemaProperties(properties: Record<Key, SchemaField>): Section[];
21
+ export {};
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sortSchemaProperties = exports.NO_TAG = exports.getNidFromUrn = void 0;
4
+ const ramda_1 = require("ramda");
5
+ /** two overloads - if you provide undefined, you might get undefined back */
6
+ exports.getNidFromUrn = ((urn) => urn === null || urn === void 0 ? void 0 : urn.split(":")[2]);
7
+ /** @ignore */
8
+ exports.NO_TAG = "-notag-common";
9
+ /**
10
+ * Schema properties are an object, so they need to be converted into an
11
+ * array, grouped by the group tag, and then sorted based on the `priority`
12
+ * attribute within their group.
13
+ */
14
+ function sortSchemaProperties(properties) {
15
+ const tagToSection = (field) => {
16
+ var _a;
17
+ // if there is a tag prefixed with `group:`, then use it
18
+ const groupTags = [
19
+ ...new Set((_a = field.tags) === null || _a === void 0 ? void 0 : _a.filter(tag => tag.startsWith("group:"))),
20
+ ];
21
+ if (groupTags === null || groupTags === void 0 ? void 0 : groupTags.length) {
22
+ const group = groupTags[0].replace("group:", "");
23
+ return group;
24
+ }
25
+ // if there is no group tag, put all those fields together in a group called "common"
26
+ return exports.NO_TAG;
27
+ };
28
+ const assocAsArray = (acum, curr) => (0, ramda_1.mergeWithKey)((k, a, b) => [...a, ...b], acum, curr);
29
+ const keyedByTag = Object.values((0, ramda_1.mapObjIndexed)((field, fieldName) => ({
30
+ // add prop anyway, just incase it's missing
31
+ [tagToSection(field)]: Object.assign(Object.assign({}, field), { $prop: fieldName }),
32
+ }), properties));
33
+ const keyedByTagSingleton = (0, ramda_1.map)(a => ({ [Object.keys(a)[0]]: [a[Object.keys(a)[0]]] }), keyedByTag);
34
+ const unsorted = (0, ramda_1.reduce)(assocAsArray, {}, keyedByTagSingleton);
35
+ const objWithSortedChildren = (0, ramda_1.mapObjIndexed)(fieldObjList => (0, ramda_1.sort)((a, b) => { var _a, _b; return ((_a = a.priority) !== null && _a !== void 0 ? _a : 0) - ((_b = b.priority) !== null && _b !== void 0 ? _b : 0); }, fieldObjList), unsorted);
36
+ // defined seperately because typescript gets confused
37
+ const unsortedFinal = Object.entries(objWithSortedChildren).map(([title, items]) => ({ title, items: (0, ramda_1.uniqBy)(f => f.$prop, items) }));
38
+ return (0, ramda_1.sortBy)(x => x.items[0].priority, unsortedFinal); // sort by priority of first child
39
+ }
40
+ exports.sortSchemaProperties = sortSchemaProperties;
@@ -0,0 +1,6 @@
1
+ import { WrappedSchema } from "@raytio/types";
2
+ export type ClientFields = {
3
+ version: string;
4
+ name: string;
5
+ };
6
+ export declare function unwrapSchema(wrapped: WrappedSchema): WrappedSchema["schema"] & Pick<WrappedSchema, "start_date" | "end_date" | "schema_type"> & ClientFields;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrapSchema = void 0;
4
+ function unwrapSchema(wrapped) {
5
+ return Object.assign(Object.assign({}, wrapped.schema), { name: wrapped.schema_name, start_date: wrapped.start_date, end_date: wrapped.end_date, version: wrapped.schema_version, schema_type: wrapped.schema_type });
6
+ }
7
+ exports.unwrapSchema = unwrapSchema;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * this is NOT meant to be machine readable, just unique.
3
+ * and it should make logical sense to a human. It is LOSSY,
4
+ * e.g. null and '' (empty string) become the same thing.
5
+ */
6
+ export declare const getConditionId: (iff: Record<string, string[]>) => string;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ // this file is not exposed to the rest of the app, it's util functions
3
+ // used by other schema helpers
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.getConditionId = void 0;
6
+ const ramda_1 = require("ramda");
7
+ // the sorting algorithm isn't important, as long as it's consistent
8
+ const sort = (0, ramda_1.sortBy)((x) => x);
9
+ /**
10
+ * this is NOT meant to be machine readable, just unique.
11
+ * and it should make logical sense to a human. It is LOSSY,
12
+ * e.g. null and '' (empty string) become the same thing.
13
+ */
14
+ const getConditionId = (iff) => sort(Object.entries(iff).map(([kk, vv]) => `${kk}=${sort(vv).join("|")}`)).join(" & ");
15
+ exports.getConditionId = getConditionId;
@@ -1 +1,2 @@
1
+ export * from "./expandSchema";
1
2
  export * from "./labels";
@@ -14,4 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./expandSchema"), exports);
17
18
  __exportStar(require("./labels"), exports);
@@ -0,0 +1,9 @@
1
+ /// <reference types="jest" />
2
+ /** like {@link Partial} but applies to all deep properties */
3
+ export type DeepPartial<T> = T | (T extends object ? {
4
+ [K in keyof T]?: DeepPartial<T[K]>;
5
+ } : T extends (infer U)[] ? DeepPartial<U>[] : T);
6
+ /** tells typescript that this function is mocked */
7
+ export declare const m: (func: unknown) => jest.Mock<any, any, any>;
8
+ /** helper to let us define type-safe partial mocks */
9
+ export declare const deepPartial: <T>(partial: DeepPartial<T>) => T;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deepPartial = exports.m = void 0;
4
+ /** tells typescript that this function is mocked */
5
+ const m = (func) => func;
6
+ exports.m = m;
7
+ /** helper to let us define type-safe partial mocks */
8
+ const deepPartial = (partial) => partial;
9
+ exports.deepPartial = deepPartial;
@@ -55,10 +55,13 @@ function getPOVerification({ PO, schema, realVers, }) {
55
55
  if (pertainingVers.length && pertainingVers.every(x => x.expired)) {
56
56
  return types_1.FieldVerification.Expired;
57
57
  }
58
- if (pertainingVers.some(x => !x.verified)) {
58
+ // the if statement above checks if every ver is expired. It is possible
59
+ // that only some are expired, so filter out those ones.
60
+ const nonExpiredPertainingVers = pertainingVers.filter(x => !x.expired);
61
+ if (nonExpiredPertainingVers.some(x => !x.verified)) {
59
62
  return types_1.FieldVerification.VerifiedFalse;
60
63
  }
61
- return pertainingVers.length
64
+ return nonExpiredPertainingVers.length
62
65
  ? types_1.FieldVerification.Verified
63
66
  : types_1.FieldVerification.NotVerified;
64
67
  }, shouldBeVerifiedProps);
@@ -89,6 +92,7 @@ function getPOVerification({ PO, schema, realVers, }) {
89
92
  nId: PO.n_id,
90
93
  realVers,
91
94
  shouldBeVerifiedProps,
95
+ verificationStatus: status,
92
96
  });
93
97
  // find the earliest expiry date if there is one
94
98
  const maybeExpiryDate = ((_c = (0, ramda_1.sortBy)(ver => +ver.expired, realVers.filter(ver => ver.belongsToNId === PO.n_id && ver.expired))[0]) === null || _c === void 0 ? void 0 : _c.expired) || undefined;
@@ -1,13 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getVerifiedBy = void 0;
4
+ const types_1 = require("@raytio/types");
4
5
  const ramda_1 = require("ramda");
5
6
  const maybeRereference_1 = require("./maybeRereference");
6
7
  // we should probably document this
7
8
  /** @internal */
8
- const getVerifiedBy = ({ nId, realVers, shouldBeVerifiedProps, }) => {
9
+ const getVerifiedBy = ({ nId, realVers, shouldBeVerifiedProps, verificationStatus, }) => {
9
10
  const mayBeVerifiedFields = Object.keys(shouldBeVerifiedProps);
10
11
  const pertainingVers = realVers
12
+ // for valid verifications, we filter out the information that came from
13
+ // now expired sources. We only ever consider expired source if the verification
14
+ // itself is expired.
15
+ .filter(realVer => realVer.expired ? verificationStatus === types_1.POVerification.Expired : true)
11
16
  .filter(x => mayBeVerifiedFields.includes(x.fieldName) &&
12
17
  // using ramda's `equals` because this needs to work for objects/arrays
13
18
  (0, ramda_1.equals)((0, maybeRereference_1.maybeRereference)(shouldBeVerifiedProps[x.fieldName]), (0, maybeRereference_1.maybeRereference)(x.value)) &&
@@ -1,4 +1,4 @@
1
- import { ProfileObject, RealVer, Schema } from "@raytio/types";
1
+ import { ProfileObject, RealVer, SafeHarbourCode, Schema } from "@raytio/types";
2
2
  /** an object listing the `xId`s for each SafeHarbourCode */
3
3
  export type SafeHarbourObj = Partial<Record<SafeHarbourCode, string[]>>;
4
4
  /** the response from {@link calcSafeHarbourScore} */
@@ -5,13 +5,6 @@ const ramda_1 = require("ramda");
5
5
  const types_1 = require("@raytio/types");
6
6
  const getPOVerification_1 = require("./getPOVerification");
7
7
  const schema_1 = require("../schema");
8
- /** @internal see #659 */
9
- var SafeHarbourCode;
10
- (function (SafeHarbourCode) {
11
- SafeHarbourCode["M1"] = "M1";
12
- SafeHarbourCode["M2"] = "M2";
13
- SafeHarbourCode["N1"] = "N1";
14
- })(SafeHarbourCode || (SafeHarbourCode = {}));
15
8
  /**
16
9
  * @internal
17
10
  * we filter to only include the POs where all the mutual fields match the
@@ -43,11 +36,11 @@ async function getFlags({ person, profileObjects, realVers, getSchema, }) {
43
36
  .filter((x) => !!x);
44
37
  // in case there are somehow duplicates (see #922)
45
38
  return (0, ramda_1.uniqBy)(x => x.nID, relevantVers)
46
- .filter(ver => { var _a; return (_a = ver.metadata) === null || _a === void 0 ? void 0 : _a["safeHarbourScore"]; })
39
+ .filter(ver => { var _a; return (_a = ver.metadata) === null || _a === void 0 ? void 0 : _a.safeHarbourScore; })
47
40
  .reduce((ac, ver) => {
48
- var _a, _b;
49
- const key = (_a = ver.metadata) === null || _a === void 0 ? void 0 : _a["safeHarbourScore"];
50
- if ((_b = ac[key]) === null || _b === void 0 ? void 0 : _b.includes(ver.xId))
41
+ var _a;
42
+ const key = ver.metadata.safeHarbourScore;
43
+ if ((_a = ac[key]) === null || _a === void 0 ? void 0 : _a.includes(ver.xId))
51
44
  return ac;
52
45
  return Object.assign(Object.assign({}, ac), { [key]: [...(ac[key] || []), ver.xId] });
53
46
  }, {});
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const __1 = require("..");
4
4
  const operations_1 = require("../operations");
5
+ const testHelpers_1 = require("../../../testHelpers");
5
6
  jest.mock("../operations");
6
7
  /**
7
8
  * in this test case:
@@ -16,18 +17,21 @@ jest.mock("../operations");
16
17
  */
17
18
  describe("getOwnRealVerifications", () => {
18
19
  beforeAll(() => {
19
- operations_1.checkOwnVerification.mockImplementation(async ({ signature }) => {
20
+ jest.fn(() => 1).mockImplementation(() => 123);
21
+ (0, testHelpers_1.m)(operations_1.checkOwnVerification).mockImplementation(async ({ signature, keyId }) => {
20
22
  if (signature === "signatureForLastNameMustermannFromN2")
21
23
  return false;
24
+ if (keyId === "thisOneIsInvalid")
25
+ return false;
22
26
  return true;
23
27
  });
24
28
  });
25
29
  it("calls the verifyCheck function for each PO, keeping only the valid ones", async () => {
26
- const profileObjects = [
30
+ const profileObjects = (0, testHelpers_1.deepPartial)([
27
31
  { n_id: "n1", properties: { fName: "Max", lName: "Mustermann" } },
28
32
  { n_id: "n2", properties: { fName: "Erika", lName: "Mustermann" } },
29
- ];
30
- const verifications = [
33
+ ]);
34
+ const verifications = (0, testHelpers_1.deepPartial)([
31
35
  {
32
36
  n_id: "nv1",
33
37
  properties: {
@@ -65,6 +69,7 @@ describe("getOwnRealVerifications", () => {
65
69
  passed: false,
66
70
  source_n_id: "n2",
67
71
  },
72
+ // legacy: key_id is not specified
68
73
  },
69
74
  ],
70
75
  },
@@ -103,14 +108,56 @@ describe("getOwnRealVerifications", () => {
103
108
  ],
104
109
  },
105
110
  },
106
- ];
111
+ {
112
+ n_id: "nv6",
113
+ properties: {
114
+ verifications: [
115
+ {
116
+ signature: "signatureForFirstNameErika",
117
+ data: {
118
+ field: "fName",
119
+ verifier_source_id: "Ministry of pike river mine re-entry",
120
+ verifier_service_id: "Minister for pike river re-entry",
121
+ verifier_id: "v1",
122
+ verification_date: "2020-08-28T23:11:20.592912",
123
+ request_div: "x2",
124
+ passed: false,
125
+ source_n_id: "n2",
126
+ },
127
+ key_id: "thisOneIsInvalid", // signature & data is good, but this key will fail
128
+ },
129
+ ],
130
+ },
131
+ },
132
+ {
133
+ n_id: "nv7",
134
+ properties: {
135
+ verifications: [
136
+ {
137
+ signature: "signatureForFirstNameErika",
138
+ data: {
139
+ field: "fName",
140
+ verifier_source_id: "Ministry of pike river mine re-entry",
141
+ verifier_service_id: "Minister for pike river re-entry",
142
+ verifier_id: "v1",
143
+ verification_date: "2020-08-28T23:11:20.592912",
144
+ request_div: "x2",
145
+ passed: false,
146
+ source_n_id: "n2",
147
+ },
148
+ key_id: "raytio", // everything is valid, this is the right key_id
149
+ },
150
+ ],
151
+ },
152
+ },
153
+ ]);
107
154
  const realVers = await (0, __1.getOwnRealVerifications)({
108
155
  profileObjects,
109
156
  verifications,
110
157
  userId: "geesepolice2002",
111
158
  });
112
- expect(operations_1.checkOwnVerification).toHaveBeenCalledTimes(3);
113
- // 3 times, not 5. Because this new method doesn't need to build a big matrix of possible combinations
159
+ expect(operations_1.checkOwnVerification).toHaveBeenCalledTimes(5);
160
+ // 5 times. Because this new method doesn't need to build a big matrix of possible combinations
114
161
  expect(realVers).toStrictEqual([
115
162
  {
116
163
  fieldName: "fName",
@@ -147,6 +194,24 @@ describe("getOwnRealVerifications", () => {
147
194
  xId: "x2",
148
195
  },
149
196
  // note how lastName is not included since it's invalid
197
+ // nv6 is not included because the key is invalid
198
+ {
199
+ fieldName: "fName",
200
+ value: "Erika",
201
+ belongsToNId: "n2",
202
+ nID: "nv7",
203
+ expired: false,
204
+ metadata: undefined,
205
+ provider: {
206
+ dataSourceNId: "Ministry of pike river mine re-entry",
207
+ date: new Date("2020-08-28T23:11:20.592Z"),
208
+ serviceProviderNId: "Minister for pike river re-entry",
209
+ verifierNId: "v1",
210
+ },
211
+ signature: "signatureForFirstNameErika",
212
+ verified: false,
213
+ xId: "x2",
214
+ },
150
215
  ]);
151
216
  });
152
217
  });
@@ -17,7 +17,8 @@ const getOwnRealVerifications = async ({ verifications, profileObjects, userId,
17
17
  // because attempting hundreds of webcrypto operations simultaneously will
18
18
  // probably upset some heritage web browser.
19
19
  for (const ver of verifications) {
20
- for (const { data, signature } of ver.properties.verifications) {
20
+ for (const verPO of ver.properties.verifications) {
21
+ const { data, signature } = verPO;
21
22
  const sourcePO = profileObjects.find(PO => PO.n_id === data.source_n_id);
22
23
  if (!sourcePO)
23
24
  continue;
@@ -34,6 +35,7 @@ const getOwnRealVerifications = async ({ verifications, profileObjects, userId,
34
35
  userId,
35
36
  value: (0, maybeRereference_1.maybeRereference)(value),
36
37
  signature,
38
+ keyId: verPO.key_id,
37
39
  });
38
40
  if (!isGenuine)
39
41
  continue;