@raytio/core 11.1.0 → 11.3.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 +17 -2
- package/README.md +123 -33
- package/dist/accessApplication/api/__tests__/fetchKeysForSubmission.test.d.ts +1 -0
- package/dist/accessApplication/api/__tests__/fetchKeysForSubmission.test.js +28 -0
- package/dist/accessApplication/api/__tests__/fetchPOsOrAOsForSubmission.test.d.ts +1 -0
- package/dist/accessApplication/api/__tests__/fetchPOsOrAOsForSubmission.test.js +23 -0
- package/dist/accessApplication/api/__tests__/fetchRelationshipsForSubmission.test.d.ts +1 -0
- package/dist/accessApplication/api/__tests__/fetchRelationshipsForSubmission.test.js +27 -0
- package/dist/accessApplication/api/__tests__/getMissingDataForInstance.test.d.ts +1 -0
- package/dist/accessApplication/api/__tests__/getMissingDataForInstance.test.js +30 -0
- package/dist/accessApplication/api/fetchKeysForSubmission.d.ts +12 -0
- package/dist/accessApplication/api/fetchKeysForSubmission.js +16 -0
- package/dist/accessApplication/api/fetchPOsOrAOsForSubmission.d.ts +6 -0
- package/dist/accessApplication/api/fetchPOsOrAOsForSubmission.js +25 -0
- package/dist/accessApplication/api/fetchRelationshipsForSubmission.d.ts +6 -0
- package/dist/accessApplication/api/fetchRelationshipsForSubmission.js +10 -0
- package/dist/accessApplication/api/getMissingDataForInstance.d.ts +10 -0
- package/dist/accessApplication/api/getMissingDataForInstance.js +28 -0
- package/dist/accessApplication/api/index.d.ts +2 -0
- package/dist/accessApplication/api/index.js +18 -0
- package/dist/accessApplication/api/legacy/__tests__/convertRelationships.test.d.ts +1 -0
- package/dist/accessApplication/api/legacy/__tests__/convertRelationships.test.js +37 -0
- package/dist/accessApplication/api/legacy/convertRelationships.d.ts +16 -0
- package/dist/accessApplication/api/legacy/convertRelationships.js +21 -0
- package/dist/accessApplication/api/legacy/index.d.ts +1 -0
- package/dist/accessApplication/api/legacy/index.js +17 -0
- package/dist/accessApplication/createAA.js +6 -5
- package/dist/accessApplication/index.d.ts +1 -0
- package/dist/accessApplication/index.js +1 -0
- package/dist/crypto/cognitoAttributes.d.ts +1 -1
- package/dist/crypto/decryptSharedData.d.ts +2 -2
- package/dist/crypto/decryptSharedData.js +2 -5
- package/dist/crypto/getAADecryptor.d.ts +18 -3
- package/dist/crypto/getAADecryptor.js +34 -6
- package/dist/crypto/helpers.d.ts +2 -2
- package/dist/general/types.d.ts +9 -0
- package/dist/general/types.js +10 -1
- package/dist/rules/calculateScore.d.ts +1 -1
- package/dist/rules/convertInstanceToRuleInput.d.ts +3 -3
- package/dist/rules/convertInstanceToRuleInput.js +5 -2
- package/dist/rules/evaluateScoreCondition.d.ts +1 -1
- package/dist/rules/helpers/__tests__/getValuesFromPath.test.js +1 -1
- package/dist/rules/helpers/addInfiniteThresholdBoundaries.d.ts +1 -1
- package/dist/rules/helpers/checkTypeofValue.d.ts +1 -1
- package/dist/rules/helpers/getValuesFromPath.d.ts +1 -1
- package/dist/rules/helpers/thresholds.d.ts +1 -1
- package/dist/rules/operators/bool.d.ts +1 -1
- package/dist/rules/operators/date.d.ts +1 -1
- package/dist/rules/operators/hfield.d.ts +1 -1
- package/dist/rules/operators/hschema.d.ts +1 -1
- package/dist/rules/operators/index.d.ts +1 -1
- package/dist/rules/operators/number.d.ts +1 -1
- package/dist/rules/operators/string.d.ts +1 -1
- package/dist/rules/types/config.d.ts +4 -3
- package/dist/rules/types/dataValueTypes.d.ts +2 -3
- package/dist/rules/types/internal.d.ts +4 -3
- package/dist/rules/validate.d.ts +2 -2
- package/dist/schema/expandSchema/__tests__/expandSchema.test.js +8 -7
- package/dist/schema/expandSchema/__tests__/i18n.test.js +1 -1
- package/dist/schema/expandSchema/__tests__/maybeUseI18n.test.js +2 -2
- package/dist/schema/expandSchema/__tests__/processSchema.test.js +6 -6
- package/dist/schema/expandSchema/addLoadingTimes.d.ts +1 -1
- package/dist/schema/expandSchema/constants.d.ts +1 -1
- package/dist/schema/expandSchema/expandSchema.d.ts +1 -1
- package/dist/schema/expandSchema/maybeUseI18n.d.ts +1 -1
- package/dist/schema/expandSchema/processSchema.d.ts +3 -4
- package/dist/schema/expandSchema/processSchema.js +2 -2
- package/dist/schema/expandSchema/removePrivateFields.d.ts +8 -6
- package/dist/schema/expandSchema/sortSchemaProperties.d.ts +3 -3
- package/dist/schema/expandSchema/unwrapSchema.d.ts +2 -6
- package/dist/schema/expandSchema/unwrapSchema.js +1 -1
- package/dist/schema/labels.d.ts +2 -1
- package/dist/testHelpers.d.ts +9 -0
- package/dist/testHelpers.js +9 -0
- package/dist/verifications/cleanInstance.d.ts +1 -1
- package/dist/verifications/getPOVerification.d.ts +1 -1
- package/dist/verifications/getPOVerification.js +6 -2
- package/dist/verifications/getVerifiedBy.js +6 -1
- package/dist/verifications/index.d.ts +0 -1
- package/dist/verifications/index.js +0 -1
- package/dist/verifications/safeHarbour.d.ts +2 -2
- package/dist/verifications/verifyCheck/__tests__/getOwnRealVerifications.test.js +74 -9
- package/dist/verifications/verifyCheck/__tests__/getSomeoneElsesRealVerifications.test.js +2 -2
- package/dist/verifications/verifyCheck/getOwnRealVerifications.d.ts +1 -1
- package/dist/verifications/verifyCheck/getOwnRealVerifications.js +3 -1
- package/dist/verifications/verifyCheck/getSomeoneElsesRealVerifications.d.ts +1 -1
- package/dist/verifications/verifyCheck/getSomeoneElsesRealVerifications.js +1 -1
- package/dist/verifications/verifyCheck/operations/__tests__/checkOwnVerification.test.js +45 -5
- package/dist/verifications/verifyCheck/operations/__tests__/checkSomeoneElsesVerifications.test.js +2 -2
- package/dist/verifications/verifyCheck/operations/__tests__/sampleBundle.json +1 -0
- package/dist/verifications/verifyCheck/operations/checkOwnVerification.d.ts +4 -3
- package/dist/verifications/verifyCheck/operations/checkOwnVerification.js +17 -8
- package/package.json +6 -42
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Schema } from "@raytio/types";
|
|
1
|
+
import type { Schema } from "@raytio/types";
|
|
2
2
|
export declare const removePrivateFields: (schema: Schema) => {
|
|
3
3
|
properties: Record<string, Omit<import("@raytio/types").SchemaField, "$id" | "allOf" | "$schema" | "definitions">>;
|
|
4
|
-
type?: import("@raytio/types").DataTypes | undefined;
|
|
5
|
-
name: string;
|
|
6
4
|
title: string;
|
|
7
5
|
description: string;
|
|
6
|
+
description_decorator?: "md" | undefined;
|
|
7
|
+
schema_type?: import("@raytio/types").SchemaType | undefined;
|
|
8
8
|
title_plural?: string | undefined;
|
|
9
9
|
schema_group?: string | undefined;
|
|
10
10
|
tags?: import("@raytio/types").SchemaTag[] | undefined;
|
|
@@ -59,8 +59,8 @@ export declare const removePrivateFields: (schema: Schema) => {
|
|
|
59
59
|
direction: "from";
|
|
60
60
|
type: string;
|
|
61
61
|
required_relationship?: boolean | undefined;
|
|
62
|
-
oneOf?:
|
|
63
|
-
anyOf?:
|
|
62
|
+
oneOf?: (import("@raytio/types").SchemaName | "instance")[] | undefined;
|
|
63
|
+
anyOf?: import("@raytio/types").SchemaName[] | undefined;
|
|
64
64
|
multiple?: boolean | undefined;
|
|
65
65
|
properties?: {
|
|
66
66
|
[fieldName: string]: import("@raytio/types").SchemaField;
|
|
@@ -83,7 +83,7 @@ export declare const removePrivateFields: (schema: Schema) => {
|
|
|
83
83
|
} | undefined;
|
|
84
84
|
onboard_properties?: {
|
|
85
85
|
profile_objects?: {
|
|
86
|
-
schema_name:
|
|
86
|
+
schema_name: import("@raytio/types").SchemaName;
|
|
87
87
|
properties: Record<string, unknown>;
|
|
88
88
|
}[] | undefined;
|
|
89
89
|
relationships?: {
|
|
@@ -104,6 +104,8 @@ export declare const removePrivateFields: (schema: Schema) => {
|
|
|
104
104
|
}[] | undefined;
|
|
105
105
|
return_to?: string | undefined;
|
|
106
106
|
} | undefined;
|
|
107
|
+
name: import("@raytio/types").SchemaName;
|
|
108
|
+
type?: import("@raytio/types").DataTypes | undefined;
|
|
107
109
|
group_title?: string | undefined;
|
|
108
110
|
verified_fields?: (string | import("@raytio/types").ConditionallyRequired)[] | undefined;
|
|
109
111
|
required?: (string | import("@raytio/types").ConditionallyRequired)[] | undefined;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { NId, SchemaField, Urn } from "@raytio/types";
|
|
1
|
+
import type { NId, SchemaField, Urn } from "@raytio/types";
|
|
2
2
|
/** two overloads - if you provide undefined, you might get undefined back */
|
|
3
3
|
export declare const getNidFromUrn: {
|
|
4
|
-
(urn: Urn):
|
|
5
|
-
(urn: Urn | undefined):
|
|
4
|
+
<IDType = NId>(urn: Urn): IDType;
|
|
5
|
+
<IDType_1 = NId>(urn: Urn | undefined): IDType_1 | undefined;
|
|
6
6
|
};
|
|
7
7
|
type Key = string;
|
|
8
8
|
type Tag = string;
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
import { WrappedSchema } from "@raytio/types";
|
|
2
|
-
export declare function unwrapSchema(wrapped: WrappedSchema): WrappedSchema["schema"] &
|
|
3
|
-
version: string;
|
|
4
|
-
start_date?: string;
|
|
5
|
-
end_date?: string;
|
|
6
|
-
};
|
|
1
|
+
import type { Schema, WrappedSchema } from "@raytio/types";
|
|
2
|
+
export declare function unwrapSchema(wrapped: WrappedSchema): WrappedSchema["schema"] & Pick<WrappedSchema, "start_date" | "end_date" | "schema_type"> & Pick<Schema, "name" | "version">;
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.unwrapSchema = void 0;
|
|
4
4
|
function unwrapSchema(wrapped) {
|
|
5
|
-
return Object.assign(Object.assign({}, wrapped.schema), { name: 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
6
|
}
|
|
7
7
|
exports.unwrapSchema = unwrapSchema;
|
package/dist/schema/labels.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
+
import type { SchemaName } from "@raytio/types";
|
|
1
2
|
/** Finds the label (on a profile object) which is the schema name */
|
|
2
|
-
export declare const findSchemaLabel: (labels: string[] | undefined) =>
|
|
3
|
+
export declare const findSchemaLabel: (labels: string[] | undefined) => SchemaName | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Mock } from "vitest";
|
|
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) => Mock<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;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FieldVerification,
|
|
1
|
+
import { FieldVerification, type NId, POVerification, type ProfileObject, type ProfileObjectForUpload, type RealVer, type Schema, type VerificationProvider } from "@raytio/types";
|
|
2
2
|
export type VerDetails = {
|
|
3
3
|
sourceNId?: NId;
|
|
4
4
|
verifiers: VerificationProvider[];
|
|
@@ -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)) &&
|
|
@@ -14,7 +14,6 @@ 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("./cleanInstance"), exports);
|
|
18
17
|
__exportStar(require("./getPOVerification"), exports);
|
|
19
18
|
__exportStar(require("./verifyCheck"), exports);
|
|
20
19
|
__exportStar(require("./getVerifiedBy"), exports);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProfileObject, RealVer, SafeHarbourCode, Schema } from "@raytio/types";
|
|
1
|
+
import { type ProfileObject, type RealVer, type SafeHarbourCode, type Schema, type SchemaName } 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} */
|
|
@@ -16,5 +16,5 @@ export declare const calcSafeHarbourScore: (data: {
|
|
|
16
16
|
person: ProfileObject;
|
|
17
17
|
profileObjects: ProfileObject[];
|
|
18
18
|
realVers: RealVer[];
|
|
19
|
-
getSchema(schemaName:
|
|
19
|
+
getSchema(schemaName: SchemaName): Promise<Schema>;
|
|
20
20
|
}) => Promise<SafeHarbourResult>;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const __1 = require("..");
|
|
4
4
|
const operations_1 = require("../operations");
|
|
5
|
-
|
|
5
|
+
const testHelpers_1 = require("../../../testHelpers");
|
|
6
|
+
vi.mock("../operations");
|
|
6
7
|
/**
|
|
7
8
|
* in this test case:
|
|
8
9
|
* - there are valid verifications for fName=Max and fName=Erika, but we don't which
|
|
@@ -16,22 +17,25 @@ jest.mock("../operations");
|
|
|
16
17
|
*/
|
|
17
18
|
describe("getOwnRealVerifications", () => {
|
|
18
19
|
beforeAll(() => {
|
|
19
|
-
|
|
20
|
+
vi.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: {
|
|
34
|
-
valid_until: "2020-08-28T23:12:35.678Z",
|
|
38
|
+
valid_until: "2020-08-28T23:12:35.678Z", // this one has expired
|
|
35
39
|
verifications: [
|
|
36
40
|
{
|
|
37
41
|
signature: "signatureForFirstNameMax",
|
|
@@ -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
|
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const getSomeoneElsesRealVerifications_1 = require("../getSomeoneElsesRealVerifications");
|
|
4
4
|
const operations_1 = require("../operations");
|
|
5
|
-
|
|
5
|
+
vi.mock("../operations");
|
|
6
6
|
const checkVerificationsResp = [
|
|
7
7
|
{
|
|
8
8
|
verified: false,
|
|
@@ -133,7 +133,7 @@ const verifications = [
|
|
|
133
133
|
];
|
|
134
134
|
describe("getSomeoneElsesRealVerifications", () => {
|
|
135
135
|
beforeEach(() => {
|
|
136
|
-
|
|
136
|
+
vi.resetAllMocks();
|
|
137
137
|
operations_1.checkSomeoneElsesVerifications.mockResolvedValue(checkVerificationsResp);
|
|
138
138
|
});
|
|
139
139
|
it("returns an empty array if provided nothing", async () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProfileObject,
|
|
1
|
+
import type { ProfileObject, RealVer, UId, Verification } from "@raytio/types";
|
|
2
2
|
/**
|
|
3
3
|
* Given a list of verifications and decrypted profile objects, this function
|
|
4
4
|
* locally verifies the credibility of the signatures in the verifications.
|
|
@@ -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;
|
|
@@ -64,7 +64,7 @@ const getSomeoneElsesRealVerifications = async ({ aId, apiUrl, verifications, pr
|
|
|
64
64
|
verified: data.passed,
|
|
65
65
|
nID,
|
|
66
66
|
belongsToNId: data.source_hashed_n_id
|
|
67
|
-
?
|
|
67
|
+
? (0, general_1.createHashedNId)(data.source_hashed_n_id, aId)
|
|
68
68
|
: data.source_n_id,
|
|
69
69
|
}));
|
|
70
70
|
return realVers;
|
|
@@ -7,8 +7,9 @@ const __1 = require("..");
|
|
|
7
7
|
const util_1 = require("../../../../util");
|
|
8
8
|
const checkOwnVerification_1 = require("../checkOwnVerification");
|
|
9
9
|
const sampleBundle_json_1 = __importDefault(require("./sampleBundle.json"));
|
|
10
|
-
|
|
11
|
-
text: async () =>
|
|
10
|
+
global.fetch = vi.fn().mockImplementation(async (url) => ({
|
|
11
|
+
text: async () => url.endsWith("raytio.pem")
|
|
12
|
+
? `-----BEGIN PUBLIC KEY-----
|
|
12
13
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAn9QtCqYa3H3ipFFU0xP3
|
|
13
14
|
n6r7KHS3GMbh0h/xzel57HhCIaXDYjUeUtgUNtzm+uElb/qzGn50xQRzVqO32vKB
|
|
14
15
|
ZAW2kYyZ2+R5ruk9CSxr7K4Vk1FtDMcUCzqxm0eycFD2xbLsN3feRc3BMjfdaQ7P
|
|
@@ -21,10 +22,29 @@ Gut0BoM+DIwDu0uZaUprz7fSgNmYHHEiIFbOMVHiOn8oZAZbJXXbUbFIUYXA8u9+
|
|
|
21
22
|
J1Z+QEpgw+rhGzOf/TSeHfMC9nNbWgYglluAJusWf2XwG/t/VlhtzviHCVGEL7HQ
|
|
22
23
|
jQE5DrM7vaTg6Gu9bjKuoeLIRzbOYK6qAWFoa0CLcN84PLjhDSRw2duatP08hcWg
|
|
23
24
|
jTgOkLWnBFE7NyRU93uPp68CAwEAAQ==
|
|
25
|
+
-----END PUBLIC KEY-----`
|
|
26
|
+
: `-----BEGIN PUBLIC KEY-----
|
|
27
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgee+uBOgOsbwjMvGN1/H
|
|
28
|
+
qpGXGJLol0Pc2KhI1fh1NBq+UGhk8PqgDd5wHZikbmrtVkvp/maIh+mbIdehY/RC
|
|
29
|
+
ftMylvebCf4Qf+5SWzQsmB1o6nBUbwJzYE2XyvxRiNLhdIeE+GgfdpA5S3l0cDJ5
|
|
30
|
+
B/1TagITmQUjThwTxDYZ6jlGJJ4NSjqlqeQrHhGWRLVQPWU8bYysX3jt3/uiv4tS
|
|
31
|
+
n3TheLGY1TMlbFrVF2Spv1WxuqMZ4bX1mIotK3yEB3TaZSZaOwlUcEZ4xY+J4Vl+
|
|
32
|
+
ZlrOgYbmzFd7UFh9UZbYZUkNSEfddEnFNFlFG3YQVt8UAumPBVJELdjiaRjTj/K4
|
|
33
|
+
62GAFyOcbcw9wcl69fPBnieBo2m2Dqf6U3wcrnvTnkMwjCewWXCH6FdbC4OllBZV
|
|
34
|
+
Nrfn6zf9yX0J8ZEDEcw9ZsNLVkyl2U+Ya/h5CQt43ip/1eNM5LpTbfqBTtAH7iUO
|
|
35
|
+
4L9rxuSJFA2Q9kZfof6kYO9EGgMFB+GM47/Q068+IiTpifvPno4ilnowyS4hbLiy
|
|
36
|
+
Os2yudW79flaz0a7rq5dLdSg9Mm5k7ETBm7WguDcocaiETmuYTJT2PozAGOC3+EP
|
|
37
|
+
w5N7mQff4ecx/880FWYKQmU9Asav1V49DWSnG0ZXQ7U24dG8ANeAgKddDviJGlsh
|
|
38
|
+
SsjKrz8LJqeoNQu30iSGZhUCAwEAAQ==
|
|
24
39
|
-----END PUBLIC KEY-----`,
|
|
25
40
|
}));
|
|
26
41
|
describe("checkOwnVerification", () => {
|
|
27
|
-
it
|
|
42
|
+
it.each `
|
|
43
|
+
keyId | result
|
|
44
|
+
${undefined} | ${true}
|
|
45
|
+
${"whatever/raytio"} | ${true}
|
|
46
|
+
${"whatever/somethingElse"} | ${false}
|
|
47
|
+
`("returns $result for a PO with keyId=$keyId", async ({ keyId, result }) => {
|
|
28
48
|
//
|
|
29
49
|
// This is an important integration test from ca. 2021-12-02.
|
|
30
50
|
// If it is failing, it means our code no longer matches the
|
|
@@ -54,7 +74,13 @@ describe("checkOwnVerification", () => {
|
|
|
54
74
|
};
|
|
55
75
|
const value = "NZ Limited Company";
|
|
56
76
|
const userId = "fd9c4903-65c2-4b75-b454-4fda6b682f3e"; // for 27july21 🦈
|
|
57
|
-
expect(await (0, checkOwnVerification_1.checkOwnVerification)({
|
|
77
|
+
expect(await (0, checkOwnVerification_1.checkOwnVerification)({
|
|
78
|
+
value,
|
|
79
|
+
signature,
|
|
80
|
+
userId,
|
|
81
|
+
verObject,
|
|
82
|
+
keyId,
|
|
83
|
+
})).toBe(result);
|
|
58
84
|
});
|
|
59
85
|
it("errors if you forget to supply the uId", async () => {
|
|
60
86
|
await expect(() => (0, checkOwnVerification_1.checkOwnVerification)({
|
|
@@ -62,8 +88,22 @@ describe("checkOwnVerification", () => {
|
|
|
62
88
|
signature: "",
|
|
63
89
|
userId: "",
|
|
64
90
|
verObject: {},
|
|
91
|
+
keyId: undefined,
|
|
65
92
|
})).rejects.toThrow(new Error("No userId supplied"));
|
|
66
93
|
});
|
|
94
|
+
it.each `
|
|
95
|
+
keyId
|
|
96
|
+
${"../../malicious.pem"}
|
|
97
|
+
${"https://example.com/malicious.pem"}
|
|
98
|
+
`("errors if you supply an invalid keyId", async ({ keyId }) => {
|
|
99
|
+
await expect(() => (0, checkOwnVerification_1.checkOwnVerification)({
|
|
100
|
+
value: "whatever",
|
|
101
|
+
signature: "whatever",
|
|
102
|
+
userId: "whatever",
|
|
103
|
+
verObject: {},
|
|
104
|
+
keyId,
|
|
105
|
+
})).rejects.toThrow(new Error("Invalid key ID"));
|
|
106
|
+
});
|
|
67
107
|
});
|
|
68
108
|
describe("checkSignature", () => {
|
|
69
109
|
it("works", async () => {
|
|
@@ -86,6 +126,6 @@ describe("checkSignature", () => {
|
|
|
86
126
|
});
|
|
87
127
|
describe("checkJsonSignature", () => {
|
|
88
128
|
it("can verify a bundled verification", async () => {
|
|
89
|
-
expect(await (0, __1.checkJsonSignature)(sampleBundle_json_1.default.data, sampleBundle_json_1.default.signature)).toBe(true);
|
|
129
|
+
expect(await (0, __1.checkJsonSignature)(sampleBundle_json_1.default.data, sampleBundle_json_1.default.signature, sampleBundle_json_1.default.key_id)).toBe(true);
|
|
90
130
|
});
|
|
91
131
|
});
|
package/dist/verifications/verifyCheck/operations/__tests__/checkSomeoneElsesVerifications.test.js
CHANGED
|
@@ -13,7 +13,7 @@ const toVerify = [
|
|
|
13
13
|
];
|
|
14
14
|
describe("checkSomeoneElsesVerifications", () => {
|
|
15
15
|
it("calls the API and filters out garbage", async () => {
|
|
16
|
-
global.fetch =
|
|
16
|
+
global.fetch = vi
|
|
17
17
|
.fn()
|
|
18
18
|
.mockImplementation()
|
|
19
19
|
// first fetch request
|
|
@@ -34,7 +34,7 @@ describe("checkSomeoneElsesVerifications", () => {
|
|
|
34
34
|
expect(result).toStrictEqual([{ verified: true }, { verified: false }]);
|
|
35
35
|
});
|
|
36
36
|
it("throws an error if the API rejects", async () => {
|
|
37
|
-
global.fetch =
|
|
37
|
+
global.fetch = vi
|
|
38
38
|
.fn()
|
|
39
39
|
.mockImplementation()
|
|
40
40
|
// first fetch request
|
|
@@ -39,5 +39,6 @@
|
|
|
39
39
|
},
|
|
40
40
|
"valid_until": "2022-03-13T02:26:20.468171"
|
|
41
41
|
},
|
|
42
|
+
"key_id": "any string/raytio",
|
|
42
43
|
"signature": "AiWWrL+S1paYOqJiOtU3qwLTCkkZjwDq3FuHl7oy14IATYOhCeHLf+ca44X1Wc6pYpTQckjKnJZL\nkfgiwNE97aymWIOc+ZZGEb5YhXRNO+inTV4k5zppaDN3n3YAGzn7zMxleh3+opzJqncNaJtpZ0Wv\na9Pu/m4WjyT5ee3Myz6VOOMuVkcaTL4FD8XT7NdCh0ybRevAZ5R9xl0YuWMhvNpf3P6ieTikHXYN\nkKbPTnAhNdBmqV4njSIR66M82Ek0d9VcsX4zhmlhpdCmGRlXLgHEyMCF4iHlCIxSeKtGaOm2QK2R\nOV/lN3VScDNWyD8lPBipcj++5ZGII6BnFFG8LlT3gY/Y/wt8KeH/xgdu0a7Lt6J/BOiGLFfscUmb\nH5K5t48gnQ5BQS+Cf/yhayMV49LlGiK9m1iPlbmuJH1L2/ZM+iLsIrSTGCU0Rpbkw7qvm0dkUNYf\nhvlj/RnUxcy0Lr/84CzLvBhFMmBX+RHlcPrCWpIiibsdaD81kRyvLY2TASLFTeHajfr+UvtP3LVs\n8NGwRQHd6c2/ptxv3ERRUnDtNASatsLe67ZHg9SeF3BDhMHZwU1neYyrBI1TMECasFli5rP5gviq\nC8ZwFQ9lnDDTidWBF8GjRl6ope4wIuNBBkOsIIeyqIJE5BRUH4LhVUnN1be696uCKnWOyOo7fkc=\n"
|
|
43
44
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { UId, VerificationPayload } from "@raytio/types";
|
|
1
|
+
import type { UId, VerificationPayload } from "@raytio/types";
|
|
2
2
|
type SingleVerToCheck = {
|
|
3
3
|
verObject: VerificationPayload<false>;
|
|
4
4
|
signature: string;
|
|
5
5
|
userId: UId;
|
|
6
6
|
value: unknown;
|
|
7
|
+
keyId: string | undefined;
|
|
7
8
|
};
|
|
8
9
|
/**
|
|
9
10
|
* checks that a json object was signed by the provided signature. Unless you're
|
|
10
11
|
* dealing with bundled verifications, you should use `getOwnRealVerifications`
|
|
11
12
|
* or `getSomeoneElsesRealVerifications` instead.
|
|
12
13
|
*/
|
|
13
|
-
export declare const checkJsonSignature: (data: unknown, signature: string) => Promise<boolean>;
|
|
14
|
-
export declare const checkOwnVerification: ({ verObject, signature, userId, value, }: SingleVerToCheck) => Promise<boolean>;
|
|
14
|
+
export declare const checkJsonSignature: (data: unknown, signature: string, keyId: string | undefined) => Promise<boolean>;
|
|
15
|
+
export declare const checkOwnVerification: ({ verObject, signature, userId, value, keyId, }: SingleVerToCheck) => Promise<boolean>;
|
|
15
16
|
export {};
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.checkOwnVerification = exports.checkJsonSignature = exports.checkSignature = void 0;
|
|
4
4
|
const util_1 = require("../../../util");
|
|
5
|
-
|
|
5
|
+
const cache = {};
|
|
6
6
|
const base64ToArrayBuffer = (str) => Uint8Array.from(atob(str), c => c.charCodeAt(0));
|
|
7
|
-
async function getJwk() {
|
|
7
|
+
async function getJwk(keyUrl) {
|
|
8
8
|
// eslint-disable-next-line fp/no-mutation
|
|
9
|
-
cache || (cache = fetch(
|
|
9
|
+
cache[keyUrl] || (cache[keyUrl] = fetch(keyUrl)
|
|
10
10
|
.then(r => r.text())
|
|
11
11
|
.then(pem => crypto.subtle.importKey("spki", base64ToArrayBuffer(pem.split("-----")[2].trim()), { name: "RSA-PSS", hash: "SHA-512" }, false, ["verify"])));
|
|
12
|
-
return cache;
|
|
12
|
+
return cache[keyUrl];
|
|
13
13
|
}
|
|
14
14
|
/** @internal exported only for tests */
|
|
15
15
|
async function checkSignature(publicCryptoKey, signature, data) {
|
|
@@ -24,16 +24,25 @@ exports.checkSignature = checkSignature;
|
|
|
24
24
|
* dealing with bundled verifications, you should use `getOwnRealVerifications`
|
|
25
25
|
* or `getSomeoneElsesRealVerifications` instead.
|
|
26
26
|
*/
|
|
27
|
-
const checkJsonSignature = async (data, signature) => {
|
|
28
|
-
const
|
|
27
|
+
const checkJsonSignature = async (data, signature, keyId) => {
|
|
28
|
+
const keyFileName = keyId ? keyId.split("/")[1] : "raytio";
|
|
29
|
+
// don't allow any special characters, e.g. to prevent
|
|
30
|
+
// someone using a keyID of "../../someOtherFile"
|
|
31
|
+
if (!keyFileName || /[^\w-]/.test(keyFileName)) {
|
|
32
|
+
throw new Error("Invalid key ID");
|
|
33
|
+
}
|
|
34
|
+
// NOTE: We have to hard code the URL, we can't use an environment
|
|
35
|
+
// variable here, since this package is used outside of the monorepo.
|
|
36
|
+
const keyUrl = `https://api-docs.rayt.io/lookups/${keyFileName}.pem`;
|
|
37
|
+
const jwk = await getJwk(keyUrl);
|
|
29
38
|
const stringified = (0, util_1.canonicalJsonify)(data);
|
|
30
39
|
const result = await checkSignature(jwk, signature, stringified);
|
|
31
40
|
return result;
|
|
32
41
|
};
|
|
33
42
|
exports.checkJsonSignature = checkJsonSignature;
|
|
34
|
-
const checkOwnVerification = async ({ verObject, signature, userId, value, }) => {
|
|
43
|
+
const checkOwnVerification = async ({ verObject, signature, userId, value, keyId, }) => {
|
|
35
44
|
if (!userId)
|
|
36
45
|
throw new Error("No userId supplied");
|
|
37
|
-
return (0, exports.checkJsonSignature)(Object.assign(Object.assign({}, verObject), { sub: userId, value }), signature);
|
|
46
|
+
return (0, exports.checkJsonSignature)(Object.assign(Object.assign({}, verObject), { sub: userId, value }), signature, keyId);
|
|
38
47
|
};
|
|
39
48
|
exports.checkOwnVerification = checkOwnVerification;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raytio/core",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "index",
|
|
6
6
|
"types": "index",
|
|
@@ -12,52 +12,16 @@
|
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
14
|
"docs": "sh ../../scripts/generate-docs.sh",
|
|
15
|
-
"build": "tsc && rimraf dist
|
|
16
|
-
"test": "
|
|
15
|
+
"build": "tsc && rimraf dist/**/__tests__",
|
|
16
|
+
"test": "vitest && yarn docs"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@raytio/maxcryptor": "3.1.0",
|
|
20
|
-
"@raytio/types": "7.
|
|
21
|
-
"ramda": "0.29.
|
|
20
|
+
"@raytio/types": "7.3.0",
|
|
21
|
+
"ramda": "0.29.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@types/ramda": "0.29.
|
|
25
|
-
"jest": "29.5.0",
|
|
26
|
-
"ts-jest": "29.1.0"
|
|
27
|
-
},
|
|
28
|
-
"jest": {
|
|
29
|
-
"transform": {
|
|
30
|
-
"^.+\\.(t|j)sx?$": "ts-jest"
|
|
31
|
-
},
|
|
32
|
-
"testEnvironment": "node",
|
|
33
|
-
"collectCoverage": false,
|
|
34
|
-
"coverageThreshold": {
|
|
35
|
-
"global": {
|
|
36
|
-
"statements": 100
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
"collectCoverageFrom": [
|
|
40
|
-
"**/*.js",
|
|
41
|
-
"**/*.ts",
|
|
42
|
-
"**/*.tsx"
|
|
43
|
-
],
|
|
44
|
-
"coveragePathIgnorePatterns": [
|
|
45
|
-
"/dist/",
|
|
46
|
-
"/coverage/"
|
|
47
|
-
],
|
|
48
|
-
"modulePathIgnorePatterns": [
|
|
49
|
-
"/dist/"
|
|
50
|
-
],
|
|
51
|
-
"reporters": [
|
|
52
|
-
"default",
|
|
53
|
-
"jest-junit"
|
|
54
|
-
],
|
|
55
|
-
"setupFilesAfterEnv": [
|
|
56
|
-
"./src/jest.setup.ts"
|
|
57
|
-
]
|
|
58
|
-
},
|
|
59
|
-
"jest-junit": {
|
|
60
|
-
"outputDirectory": "../../tmp"
|
|
24
|
+
"@types/ramda": "0.29.7"
|
|
61
25
|
},
|
|
62
26
|
"engineStrict": true,
|
|
63
27
|
"engines": {
|