@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.
- package/CHANGELOG.md +16 -1
- package/README.md +100 -1
- package/dist/crypto/getAADecryptor.js +32 -4
- package/dist/schema/expandSchema/__tests__/addLoadingTimes.test.d.ts +1 -0
- package/dist/schema/expandSchema/__tests__/addLoadingTimes.test.js +24 -0
- package/dist/schema/expandSchema/__tests__/expandSchema.test.d.ts +1 -0
- package/dist/schema/expandSchema/__tests__/expandSchema.test.js +96 -0
- package/dist/schema/expandSchema/__tests__/i18n.test.d.ts +1 -0
- package/dist/schema/expandSchema/__tests__/i18n.test.js +32 -0
- package/dist/schema/expandSchema/__tests__/maybeUseI18n.test.d.ts +1 -0
- package/dist/schema/expandSchema/__tests__/maybeUseI18n.test.js +98 -0
- package/dist/schema/expandSchema/__tests__/processSchema.test.d.ts +1 -0
- package/dist/schema/expandSchema/__tests__/processSchema.test.js +326 -0
- package/dist/schema/expandSchema/__tests__/sortSchemaProperties.test.d.ts +1 -0
- package/dist/schema/expandSchema/__tests__/sortSchemaProperties.test.js +182 -0
- package/dist/schema/expandSchema/__tests__/util.test.d.ts +1 -0
- package/dist/schema/expandSchema/__tests__/util.test.js +19 -0
- package/dist/schema/expandSchema/addLoadingTimes.d.ts +2 -0
- package/dist/schema/expandSchema/addLoadingTimes.js +12 -0
- package/dist/schema/expandSchema/constants.d.ts +2 -0
- package/dist/schema/expandSchema/constants.js +11 -0
- package/dist/schema/expandSchema/expandSchema.d.ts +7 -0
- package/dist/schema/expandSchema/expandSchema.js +19 -0
- package/dist/schema/expandSchema/i18n.d.ts +5 -0
- package/dist/schema/expandSchema/i18n.js +20 -0
- package/dist/schema/expandSchema/index.d.ts +3 -0
- package/dist/schema/expandSchema/index.js +21 -0
- package/dist/schema/expandSchema/maybeUseI18n.d.ts +2 -0
- package/dist/schema/expandSchema/maybeUseI18n.js +40 -0
- package/dist/schema/expandSchema/processSchema.d.ts +3 -0
- package/dist/schema/expandSchema/processSchema.js +94 -0
- package/dist/schema/expandSchema/removePrivateFields.d.ts +121 -0
- package/dist/schema/expandSchema/removePrivateFields.js +15 -0
- package/dist/schema/expandSchema/sortSchemaProperties.d.ts +21 -0
- package/dist/schema/expandSchema/sortSchemaProperties.js +40 -0
- package/dist/schema/expandSchema/unwrapSchema.d.ts +6 -0
- package/dist/schema/expandSchema/unwrapSchema.js +7 -0
- package/dist/schema/expandSchema/util.d.ts +6 -0
- package/dist/schema/expandSchema/util.js +15 -0
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/testHelpers.d.ts +9 -0
- package/dist/testHelpers.js +9 -0
- package/dist/verifications/getPOVerification.js +6 -2
- package/dist/verifications/getVerifiedBy.js +6 -1
- package/dist/verifications/safeHarbour.d.ts +1 -1
- package/dist/verifications/safeHarbour.js +4 -11
- package/dist/verifications/verifyCheck/__tests__/getOwnRealVerifications.test.js +72 -7
- package/dist/verifications/verifyCheck/getOwnRealVerifications.js +3 -1
- package/dist/verifications/verifyCheck/operations/__tests__/checkOwnVerification.test.js +45 -5
- package/dist/verifications/verifyCheck/operations/__tests__/sampleBundle.json +1 -0
- package/dist/verifications/verifyCheck/operations/checkOwnVerification.d.ts +3 -2
- package/dist/verifications/verifyCheck/operations/checkOwnVerification.js +15 -8
- 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,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;
|
package/dist/schema/index.d.ts
CHANGED
package/dist/schema/index.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
49
|
-
const key =
|
|
50
|
-
if ((
|
|
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
|
-
|
|
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(
|
|
113
|
-
//
|
|
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
|
|
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;
|