upgrade to 1.1.0
This commit is contained in:
1 parent
02c95d89bb
commit
f5893a107d
46 files changed
+3755
-2882
No files matched your search
@@ -1,2 +0,0 @@
|
|||||||
node_modules
|
|
||||||
.env
|
|
||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
.env
|
**/.env*
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2025 JLINC Labs
|
Copyright (c) 2026 JLINC, Inc
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
export function produceAgreement({ data, shortName, role, archive }: {
|
||||||
|
data: any;
|
||||||
|
shortName: any;
|
||||||
|
role: any;
|
||||||
|
archive: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
export function processAgreement({ agreementId, shortName, role, archive }: {
|
||||||
|
agreementId: any;
|
||||||
|
shortName: any;
|
||||||
|
role: any;
|
||||||
|
archive: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
export function getAgreement({ agreementId, includeSignatures }: {
|
||||||
|
agreementId: any;
|
||||||
|
includeSignatures: any;
|
||||||
|
}): Promise<any>;
|
||||||
Vendored
+36
@@ -0,0 +1,36 @@
|
|||||||
|
"use strict";
|
||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig, getDefault } = require('./config.js');
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function produceAgreement({ data, shortName, role, archive }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
const defaultArchive = { url: cfg.archiveUrl, key: cfg.archiveKey };
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/agreement/produce'), {
|
||||||
|
data,
|
||||||
|
shortName,
|
||||||
|
role,
|
||||||
|
archive: archive || defaultArchive,
|
||||||
|
}, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
async function processAgreement({ agreementId, shortName, role, archive }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
const defaultArchive = { url: cfg.archiveUrl, key: cfg.archiveKey };
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/agreement/process'), {
|
||||||
|
agreementId: agreementId || getDefault('agreementId'),
|
||||||
|
shortName,
|
||||||
|
role,
|
||||||
|
archive: archive || defaultArchive,
|
||||||
|
}, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
async function getAgreement({ agreementId, includeSignatures }) {
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/agreement/get'), { agreementId: agreementId || getDefault('agreementId'), includeSignatures }, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
module.exports = { produceAgreement, processAgreement, getAgreement };
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
export function getAudits({ agreementId, eventId, meta }: {
|
||||||
|
agreementId: any;
|
||||||
|
eventId: any;
|
||||||
|
meta: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
export function verifyAudit({ audits, shortNames }: {
|
||||||
|
audits: any;
|
||||||
|
shortNames: any;
|
||||||
|
}): Promise<any>;
|
||||||
Vendored
+23
@@ -0,0 +1,23 @@
|
|||||||
|
"use strict";
|
||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig, getDefault } = require('./config.js');
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
function _getArchiveUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.archiveUrl}${path}`;
|
||||||
|
}
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function getAudits({ agreementId, eventId, meta }) {
|
||||||
|
return (await axios.post(_getArchiveUrl('/api/v1/audit/get'), { agreementId: agreementId || getDefault('agreementId'), eventId, meta }, { headers: _headers(getConfig().archiveKey) })).data;
|
||||||
|
}
|
||||||
|
async function verifyAudit({ audits, shortNames }) {
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/audit/verify'), { audits, shortNames }, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
module.exports = { getAudits, verifyAudit };
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
export function auth({ subject, action, resource }: {
|
||||||
|
subject: any;
|
||||||
|
action: any;
|
||||||
|
resource: any;
|
||||||
|
}): Promise<any>;
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
"use strict";
|
||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig } = require('./config.js');
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function auth({ subject, action, resource }) {
|
||||||
|
return (await axios.post(_getUrl('/api/v1/auth'), { subject, action, resource }, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
module.exports = { auth };
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
export function init(cfg: any, defaultOpts: any): void;
|
||||||
|
export function getConfig(): {};
|
||||||
|
export function getDefaults(): {};
|
||||||
|
export function getDefault(key: any): any;
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
"use strict";
|
||||||
|
let config = {};
|
||||||
|
let defaults = {};
|
||||||
|
function init(cfg, defaultOpts) {
|
||||||
|
config = { ...cfg };
|
||||||
|
if (defaultOpts) {
|
||||||
|
defaults = { ...defaultOpts };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
function getDefaults() {
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
function getDefault(key) {
|
||||||
|
return defaults[key];
|
||||||
|
}
|
||||||
|
module.exports = { init, getConfig, getDefaults, getDefault };
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
export function getDomains({ fedidUrl, auth: authPayload }: {
|
||||||
|
fedidUrl: any;
|
||||||
|
auth: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
export function getEntity({ shortName }: {
|
||||||
|
shortName: any;
|
||||||
|
}): Promise<axios.AxiosResponse<any, {
|
||||||
|
shortName: any;
|
||||||
|
}, {}, any>>;
|
||||||
|
export function createEntity({ fedidUrl, shortName }: {
|
||||||
|
fedidUrl: any;
|
||||||
|
shortName: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
import axios = require("axios");
|
||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
"use strict";
|
||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig } = require('./config.js');
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function getDomains({ fedidUrl, auth: authPayload }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/entity/domains/get'), {
|
||||||
|
fedidUrl: fedidUrl || cfg.fedidUrl,
|
||||||
|
auth: authPayload,
|
||||||
|
}, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
async function createEntity({ fedidUrl, shortName }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/entity/create'), {
|
||||||
|
fedidUrl: fedidUrl || cfg.fedidUrl,
|
||||||
|
shortName,
|
||||||
|
}, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
async function getEntity({ shortName }) {
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/entity/get'), { shortName }, { headers: _headers() }));
|
||||||
|
}
|
||||||
|
module.exports = { getDomains, getEntity, createEntity };
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
export function produceEvent({ type, senderShortName, recipientShortName, agreementId, meta, data, archive }: {
|
||||||
|
type: any;
|
||||||
|
senderShortName: any;
|
||||||
|
recipientShortName: any;
|
||||||
|
agreementId: any;
|
||||||
|
meta: any;
|
||||||
|
data: any;
|
||||||
|
archive: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
export function getEvent({ eventId, meta }: {
|
||||||
|
eventId: any;
|
||||||
|
meta: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
export function processEvent({ eventId, shortName, archive }: {
|
||||||
|
eventId: any;
|
||||||
|
shortName: any;
|
||||||
|
archive: any;
|
||||||
|
}): Promise<any>;
|
||||||
Vendored
+38
@@ -0,0 +1,38 @@
|
|||||||
|
"use strict";
|
||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig, getDefault } = require('./config.js');
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function produceEvent({ type, senderShortName, recipientShortName, agreementId, meta, data, archive }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
const defaultArchive = { url: cfg.archiveUrl, key: cfg.archiveKey };
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/event/produce'), {
|
||||||
|
type,
|
||||||
|
senderShortName,
|
||||||
|
recipientShortName,
|
||||||
|
agreementId: agreementId || getDefault('agreementId'),
|
||||||
|
meta,
|
||||||
|
data,
|
||||||
|
archive: archive || defaultArchive,
|
||||||
|
}, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
async function getEvent({ eventId, meta }) {
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/event/get'), { eventId, meta }, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
async function processEvent({ eventId, shortName, archive }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
const defaultArchive = { url: cfg.archiveUrl, key: cfg.archiveKey };
|
||||||
|
return (await axios.post(_getUrl('/api/v1/data/event/process'), {
|
||||||
|
eventId,
|
||||||
|
shortName,
|
||||||
|
archive: archive || defaultArchive,
|
||||||
|
}, { headers: _headers() })).data;
|
||||||
|
}
|
||||||
|
module.exports = { produceEvent, getEvent, processEvent };
|
||||||
Vendored
+13
-58
@@ -1,58 +1,13 @@
|
|||||||
export type JLINCConfig = {
|
export let init: typeof import("./config.js").init;
|
||||||
debug?: boolean | undefined;
|
export let auth: typeof import("./auth.js").auth;
|
||||||
systemPrefix?: string | undefined;
|
export let getDomains: typeof import("./entity.js").getDomains;
|
||||||
defaultAgreementId?: string | undefined;
|
export let getEntity: typeof import("./entity.js").getEntity;
|
||||||
domain?: string | null | undefined;
|
export let createEntity: typeof import("./entity.js").createEntity;
|
||||||
dataStoreApiUrl?: string | null | undefined;
|
export let produceAgreement: typeof import("./agreement.js").produceAgreement;
|
||||||
dataStoreApiKey?: string | null | undefined;
|
export let processAgreement: typeof import("./agreement.js").processAgreement;
|
||||||
archiveApiUrl?: string | null | undefined;
|
export let getAgreement: typeof import("./agreement.js").getAgreement;
|
||||||
archiveApiKey?: string | null | undefined;
|
export let produceEvent: typeof import("./event.js").produceEvent;
|
||||||
};
|
export let getEvent: typeof import("./event.js").getEvent;
|
||||||
export type JLINCProduceEventData = {
|
export let processEvent: typeof import("./event.js").processEvent;
|
||||||
to?: string | undefined;
|
export let getAudits: typeof import("./audit.js").getAudits;
|
||||||
from?: string | undefined;
|
export let verifyAudit: typeof import("./audit.js").verifyAudit;
|
||||||
agreementId?: string | null | undefined;
|
|
||||||
payload?: any;
|
|
||||||
auth?: any;
|
|
||||||
};
|
|
||||||
export type JLINCProcessEventData = {
|
|
||||||
to?: string | undefined;
|
|
||||||
eventId?: string | undefined;
|
|
||||||
auth?: any;
|
|
||||||
};
|
|
||||||
export type JLINCProduceAgreementData = {
|
|
||||||
requiredSigners?: string[] | undefined;
|
|
||||||
signer?: string | undefined;
|
|
||||||
uri?: string | undefined;
|
|
||||||
purposes?: string[] | undefined;
|
|
||||||
caveats?: string[] | undefined;
|
|
||||||
validRoles?: string[] | undefined;
|
|
||||||
role?: string | undefined;
|
|
||||||
auth?: any;
|
|
||||||
};
|
|
||||||
export type JLINCProcessAgreementData = {
|
|
||||||
agreementId?: string | undefined;
|
|
||||||
signer?: string | undefined;
|
|
||||||
role?: string | undefined;
|
|
||||||
auth?: any;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* @param {JLINCConfig} data - The configuration object for the application.
|
|
||||||
*/
|
|
||||||
export function jlincInit(data: JLINCConfig): void;
|
|
||||||
/**
|
|
||||||
* @param {JLINCProduceEventData} data - The data required for producing an event.
|
|
||||||
*/
|
|
||||||
export function jlincProduceEvent(data: JLINCProduceEventData): Promise<any>;
|
|
||||||
/**
|
|
||||||
* @param {JLINCProcessEventData} data - The data required for processing an event.
|
|
||||||
*/
|
|
||||||
export function jlincProcessEvent(data: JLINCProcessEventData): Promise<any>;
|
|
||||||
/**
|
|
||||||
* @param {JLINCProduceAgreementData} data - The data required for producing an agreement.
|
|
||||||
*/
|
|
||||||
export function jlincProduceAgreement(data: JLINCProduceAgreementData): Promise<any>;
|
|
||||||
/**
|
|
||||||
* @param {JLINCProcessAgreementData} data - The data required for processing an agreement.
|
|
||||||
*/
|
|
||||||
export function jlincProcessAgreement(data: JLINCProcessAgreementData): Promise<any>;
|
|
||||||
Vendored
+15
-262
@@ -1,263 +1,16 @@
|
|||||||
const axios = require("axios");
|
"use strict";
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCConfig
|
|
||||||
* @property {boolean} [debug]
|
|
||||||
* @property {string} [systemPrefix]
|
|
||||||
* @property {string} [defaultAgreementId]
|
|
||||||
* @property {string|null} [domain]
|
|
||||||
* @property {string|null} [dataStoreApiUrl]
|
|
||||||
* @property {string|null} [dataStoreApiKey]
|
|
||||||
* @property {string|null} [archiveApiUrl]
|
|
||||||
* @property {string|null} [archiveApiKey]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCProduceEventData
|
|
||||||
* @property {string} [to]
|
|
||||||
* @property {string} [from]
|
|
||||||
* @property {string|null} [agreementId]
|
|
||||||
* @property {any} [payload]
|
|
||||||
* @property {any} [auth]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCProcessEventData
|
|
||||||
* @property {string} [to]
|
|
||||||
* @property {string} [eventId]
|
|
||||||
* @property {any} [auth]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCProduceAgreementData
|
|
||||||
* @property {Array<string>} [requiredSigners]
|
|
||||||
* @property {string} [signer]
|
|
||||||
* @property {string} [uri]
|
|
||||||
* @property {Array<string>} [purposes]
|
|
||||||
* @property {Array<string>} [caveats]
|
|
||||||
* @property {Array<string>} [validRoles]
|
|
||||||
* @property {string} [role]
|
|
||||||
* @property {any} [auth]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCProcessAgreementData
|
|
||||||
* @property {string} [agreementId]
|
|
||||||
* @property {string} [signer]
|
|
||||||
* @property {string} [role]
|
|
||||||
* @property {any} [auth]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCConfig} config - The configuration object for the library
|
|
||||||
*/
|
|
||||||
let config = {
|
|
||||||
debug: false,
|
|
||||||
systemPrefix: 'my-system',
|
|
||||||
defaultAgreementId: '00000000-0000-0000-0000-000000000000',
|
|
||||||
domain: null,
|
|
||||||
dataStoreApiUrl: null,
|
|
||||||
dataStoreApiKey: null,
|
|
||||||
archiveApiUrl: null,
|
|
||||||
archiveApiKey: null,
|
|
||||||
}
|
|
||||||
|
|
||||||
const entities = new Set();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} input
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function sanitize(input) {
|
|
||||||
return input.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} dir
|
|
||||||
* @param {any} payload
|
|
||||||
* @returns {Promise<any>}
|
|
||||||
*/
|
|
||||||
async function postToApi(dir, payload) {
|
|
||||||
const response = await axios.post(
|
|
||||||
`${config.dataStoreApiUrl}/api/v1/data/${dir}`,
|
|
||||||
payload,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
'Authorization': `Bearer ${config.dataStoreApiKey}`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} entityShortName
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
async function setEntity(name) {
|
|
||||||
const entityShortName = `${config.systemPrefix}-${sanitize(name)}@${config.domain}`;
|
|
||||||
if (!entities.has(entityShortName)) {
|
|
||||||
try {
|
|
||||||
await postToApi(`entity/get`, { shortName: entityShortName });
|
|
||||||
} catch (e) {
|
|
||||||
await postToApi(`entity/create`, { shortName: entityShortName });
|
|
||||||
}
|
|
||||||
entities.add(entityShortName);
|
|
||||||
}
|
|
||||||
return entityShortName
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCConfig} data - The configuration object for the application.
|
|
||||||
*/
|
|
||||||
function jlincInit(data) {
|
|
||||||
config = {
|
|
||||||
...config,
|
|
||||||
...data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getDomain() {
|
|
||||||
if (!config.domain) {
|
|
||||||
const domains = await postToApi(`entity/domains/get`, {});
|
|
||||||
config.domain = domains[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCProduceEventData} data - The data required for producing an event.
|
|
||||||
*/
|
|
||||||
async function jlincProduceEvent(data) {
|
|
||||||
let res = null;
|
|
||||||
try {
|
|
||||||
await getDomain();
|
|
||||||
const senderShortName = await setEntity(data.from)
|
|
||||||
const recipientShortName = await setEntity(data.to)
|
|
||||||
const agreementId = data.agreementId ?? config.defaultAgreementId;
|
|
||||||
const postData = {
|
|
||||||
type: 'data',
|
|
||||||
senderShortName,
|
|
||||||
recipientShortName,
|
|
||||||
agreementId,
|
|
||||||
data: data.payload,
|
|
||||||
archive: {
|
|
||||||
url: config.archiveApiUrl,
|
|
||||||
key: config.archiveApiKey,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (data.auth) postData.auth = data.auth;
|
|
||||||
res = await postToApi(`event/produce`, postData);
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(JSON.stringify({ res }, null, 2));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("[JLINC] Failed to produce event:", error.message);
|
|
||||||
if (config.debug) console.error(error)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCProcessEventData} data - The data required for processing an event.
|
|
||||||
*/
|
|
||||||
async function jlincProcessEvent(data) {
|
|
||||||
let res = null;
|
|
||||||
try {
|
|
||||||
await getDomain();
|
|
||||||
const shortName = await setEntity(data.to)
|
|
||||||
const postData = {
|
|
||||||
type: 'data',
|
|
||||||
shortName,
|
|
||||||
eventId: data.eventId,
|
|
||||||
archive: {
|
|
||||||
url: config.archiveApiUrl,
|
|
||||||
key: config.archiveApiKey,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (data.auth) postData.auth = data.auth;
|
|
||||||
res = await postToApi(`event/process`, postData);
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(JSON.stringify({ res }, null, 2));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("[JLINC] Failed to process event:", error.message);
|
|
||||||
if (config.debug) console.error(error)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCProduceAgreementData} data - The data required for producing an agreement.
|
|
||||||
*/
|
|
||||||
async function jlincProduceAgreement(data) {
|
|
||||||
let res = null;
|
|
||||||
try {
|
|
||||||
await getDomain();
|
|
||||||
const shortNames = [];
|
|
||||||
for (const id of data.requiredSigners) {
|
|
||||||
shortNames.push(await setEntity(id))
|
|
||||||
}
|
|
||||||
const shortName = await setEntity(data.signer)
|
|
||||||
const postData = {
|
|
||||||
data: {
|
|
||||||
uri: data.uri,
|
|
||||||
purposes: data.purposes,
|
|
||||||
caveats: data.caveats,
|
|
||||||
shortNames,
|
|
||||||
validRoles: data.validRoles,
|
|
||||||
},
|
|
||||||
shortName,
|
|
||||||
role: data.role,
|
|
||||||
archive: {
|
|
||||||
url: config.archiveApiUrl,
|
|
||||||
key: config.archiveApiKey,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (data.auth) postData.auth = data.auth;
|
|
||||||
res = await postToApi(`agreement/produce`, postData);
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(JSON.stringify({ res }, null, 2));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("[JLINC] Failed to produce agreement:", error.message);
|
|
||||||
if (config.debug) console.error(error)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCProcessAgreementData} data - The data required for processing an agreement.
|
|
||||||
*/
|
|
||||||
async function jlincProcessAgreement(data) {
|
|
||||||
let res = null;
|
|
||||||
try {
|
|
||||||
await getDomain();
|
|
||||||
const shortName = await setEntity(data.signer)
|
|
||||||
const postData = {
|
|
||||||
agreementId: data.agreementId,
|
|
||||||
shortName,
|
|
||||||
role: data.role,
|
|
||||||
archive: {
|
|
||||||
url: config.archiveApiUrl,
|
|
||||||
key: config.archiveApiKey,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (data.auth) postData.auth = data.auth;
|
|
||||||
res = await postToApi(`agreement/process`, postData);
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(JSON.stringify({ res }, null, 2));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("[JLINC] Failed to process agreement:", error.message);
|
|
||||||
if (config.debug) console.error(error)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
jlincInit,
|
init: require('./config.js').init,
|
||||||
jlincProduceEvent,
|
auth: require('./auth.js').auth,
|
||||||
jlincProcessEvent,
|
getDomains: require('./entity.js').getDomains,
|
||||||
jlincProduceAgreement,
|
getEntity: require('./entity.js').getEntity,
|
||||||
jlincProcessAgreement,
|
createEntity: require('./entity.js').createEntity,
|
||||||
}
|
produceAgreement: require('./agreement.js').produceAgreement,
|
||||||
|
processAgreement: require('./agreement.js').processAgreement,
|
||||||
|
getAgreement: require('./agreement.js').getAgreement,
|
||||||
|
produceEvent: require('./event.js').produceEvent,
|
||||||
|
getEvent: require('./event.js').getEvent,
|
||||||
|
processEvent: require('./event.js').processEvent,
|
||||||
|
getAudits: require('./audit.js').getAudits,
|
||||||
|
verifyAudit: require('./audit.js').verifyAudit,
|
||||||
|
};
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
export { init, getConfig, getDefaults, getDefault } from "./config.js";
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.getDefault = exports.getDefaults = exports.getConfig = exports.init = void 0;
|
||||||
|
var config_js_1 = require("./config.js");
|
||||||
|
Object.defineProperty(exports, "init", { enumerable: true, get: function () { return config_js_1.init; } });
|
||||||
|
Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return config_js_1.getConfig; } });
|
||||||
|
Object.defineProperty(exports, "getDefaults", { enumerable: true, get: function () { return config_js_1.getDefaults; } });
|
||||||
|
Object.defineProperty(exports, "getDefault", { enumerable: true, get: function () { return config_js_1.getDefault; } });
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
const jlinc = require('./index.js');
|
||||||
|
module.exports = jlinc;
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
declare const _exports: {
|
||||||
|
init: (cfg: object, defaultOpts?: object) => void;
|
||||||
|
auth: (params: { subject: any; action: any; resource: any }) => Promise<any>;
|
||||||
|
getDomains: (params: { fedidUrl?: string; auth?: any }) => Promise<any>;
|
||||||
|
getEntity: (params: { shortName: string }) => Promise<any>;
|
||||||
|
createEntity: (params: { fedidUrl?: string; shortName: string }) => Promise<any>;
|
||||||
|
produceAgreement: (params: { data: any; shortName: string; role: string; archive?: any }) => Promise<any>;
|
||||||
|
processAgreement: (params: { agreementId?: string; shortName: string; role: string; archive?: any }) => Promise<any>;
|
||||||
|
getAgreement: (params: { agreementId?: string; includeSignatures?: boolean }) => Promise<any>;
|
||||||
|
produceEvent: (params: { type: string; senderShortName: string; recipientShortName: string; agreementId?: string; meta?: any; data: any; archive?: any }) => Promise<any>;
|
||||||
|
getEvent: (params: { eventId?: string; meta?: any }) => Promise<any>;
|
||||||
|
processEvent: (params: { eventId: string; shortName: string; archive?: any }) => Promise<any>;
|
||||||
|
getAudits: (params: { agreementId?: string; eventId?: string; meta?: any }) => Promise<any>;
|
||||||
|
verifyAudit: (params: { audits: string[]; shortNames: string[] }) => Promise<any>;
|
||||||
|
};
|
||||||
|
export = _exports;
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
export function init(cfg: object, defaultOpts?: object): void;
|
||||||
|
export function auth(params: { subject: any; action: any; resource: any }): Promise<any>;
|
||||||
|
export function getDomains(params: { fedidUrl?: string; auth?: any }): Promise<any>;
|
||||||
|
export function getEntity(params: { shortName: string }): Promise<any>;
|
||||||
|
export function createEntity(params: { fedidUrl?: string; shortName: string }): Promise<any>;
|
||||||
|
export function produceAgreement(params: { data: any; shortName: string; role: string; archive?: any }): Promise<any>;
|
||||||
|
export function processAgreement(params: { agreementId?: string; shortName: string; role: string; archive?: any }): Promise<any>;
|
||||||
|
export function getAgreement(params: { agreementId?: string; includeSignatures?: boolean }): Promise<any>;
|
||||||
|
export function produceEvent(params: { type: string; senderShortName: string; recipientShortName: string; agreementId?: string; meta?: any; data: any; archive?: any }): Promise<any>;
|
||||||
|
export function getEvent(params: { eventId?: string; meta?: any }): Promise<any>;
|
||||||
|
export function processEvent(params: { eventId: string; shortName: string; archive?: any }): Promise<any>;
|
||||||
|
export function getAudits(params: { agreementId?: string; eventId?: string; meta?: any }): Promise<any>;
|
||||||
|
export function verifyAudit(params: { audits: string[]; shortNames: string[] }): Promise<any>;
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import jlinc from './index.js';
|
||||||
|
|
||||||
|
export const { init, getConfig, getDefaults, getDefault } = jlinc;
|
||||||
|
export const { auth } = jlinc;
|
||||||
|
export const { getDomains, getEntity, createEntity } = jlinc;
|
||||||
|
export const { produceAgreement, processAgreement, getAgreement } = jlinc;
|
||||||
|
export const { produceEvent, getEvent, processEvent } = jlinc;
|
||||||
|
export const { getAudits, verifyAudit } = jlinc;
|
||||||
|
export default jlinc;
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
JLINC_DATA_STORE_API_URL="http://localhost:9090"
|
|
||||||
JLINC_DATA_STORE_API_KEY=""
|
|
||||||
|
|
||||||
JLINC_ARCHIVE_API_URL="http://localhost:9090"
|
|
||||||
JLINC_ARCHIVE_API_KEY=""
|
|
||||||
|
|
||||||
JLINC_SYSTEM_PREFIX="TestJlinc"
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
testEnvironment: 'node',
|
||||||
|
transform: {
|
||||||
|
'^.+\\.tsx?$': 'ts-jest',
|
||||||
|
},
|
||||||
|
};
|
||||||
Generated
+1439
-1607
File diff suppressed because it is too large.
Load diff
+31
-21
@@ -1,17 +1,26 @@
|
|||||||
{
|
{
|
||||||
"name": "@jlinc/sdk",
|
"name": "@jlinc/sdk",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"description": "JLINC SDK for utilizing the JLINC API.",
|
"description": "JLINC SDK for utilizing the JLINC API.",
|
||||||
"main": "dist/index.js",
|
"main": "./dist/jlinc.cjs",
|
||||||
"types": "dist/index.d.ts",
|
"types": "./dist/jlinc.d.ts",
|
||||||
"scripts": {
|
"exports": {
|
||||||
"test": "jest",
|
".": {
|
||||||
"build": "rm -rf dist && tsc --project tsconfig.build.json && cp src/index.js dist/"
|
"import": {
|
||||||
|
"types": "./dist/jlinc.d.ts",
|
||||||
|
"default": "./dist/jlinc.mjs"
|
||||||
},
|
},
|
||||||
"homepage": "https://www.jlinc.com/",
|
"require": {
|
||||||
"repository": {
|
"types": "./dist/jlinc.cjs.d.ts",
|
||||||
"type": "git",
|
"default": "./dist/jlinc.cjs"
|
||||||
"url": "https://gitea.jlinc.io/jlinc-labs/jlinc-sdk-node"
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "rm -rf dist && tsc --project tsconfig.build.json && cp src/jlinc.cjs dist/ && cp src/jlinc.mjs dist/ && cp src/jlinc.d.ts dist/ && cp src/jlinc.cjs.d.ts dist/",
|
||||||
|
"test": "jest --runInBand --testPathPattern \"index\\.test\\.js\"",
|
||||||
|
"test:integration": "jest --runInBand --testPathPattern \"integration/.*\\.test\\.js\"",
|
||||||
|
"test:integration-ts": "jest --runInBand --testPathPattern \"integration/.*\\.test\\.ts\""
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"jlinc",
|
"jlinc",
|
||||||
@@ -19,17 +28,18 @@
|
|||||||
"governance",
|
"governance",
|
||||||
"authorization"
|
"authorization"
|
||||||
],
|
],
|
||||||
"author": "Ben Curtis",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"axios": "^1.14.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"dotenv": "^17.4.1",
|
|
||||||
"jest": "^30.3.0",
|
|
||||||
"typescript": "^6.0.2"
|
|
||||||
},
|
|
||||||
"files": [
|
"files": [
|
||||||
"dist/*"
|
"dist/*"
|
||||||
]
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.7.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/jest": "^29.0.0",
|
||||||
|
"@types/node": "^20.0.0",
|
||||||
|
"dotenv": "^16.0.0",
|
||||||
|
"jest": "^29.0.0",
|
||||||
|
"ts-jest": "^29.4.15"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig, getDefault } = require('./config.js');
|
||||||
|
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function produceAgreement({ data, shortName, role, archive }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
const defaultArchive = { url: cfg.archiveUrl, key: cfg.archiveKey };
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/agreement/produce'),
|
||||||
|
{
|
||||||
|
data,
|
||||||
|
shortName,
|
||||||
|
role,
|
||||||
|
archive: archive || defaultArchive,
|
||||||
|
},
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processAgreement({ agreementId, shortName, role, archive }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
const defaultArchive = { url: cfg.archiveUrl, key: cfg.archiveKey };
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/agreement/process'),
|
||||||
|
{
|
||||||
|
agreementId: agreementId || getDefault('agreementId'),
|
||||||
|
shortName,
|
||||||
|
role,
|
||||||
|
archive: archive || defaultArchive,
|
||||||
|
},
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAgreement({ agreementId, includeSignatures }) {
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/agreement/get'),
|
||||||
|
{ agreementId: agreementId || getDefault('agreementId'), includeSignatures },
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { produceAgreement, processAgreement, getAgreement };
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig, getDefault } = require('./config.js');
|
||||||
|
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getArchiveUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.archiveUrl}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAudits({ agreementId, eventId, meta }) {
|
||||||
|
return (await axios.post(
|
||||||
|
_getArchiveUrl('/api/v1/audit/get'),
|
||||||
|
{ agreementId: agreementId || getDefault('agreementId'), eventId, meta },
|
||||||
|
{ headers: _headers(getConfig().archiveKey) },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function verifyAudit({ audits, shortNames }) {
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/audit/verify'),
|
||||||
|
{ audits, shortNames },
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getAudits, verifyAudit };
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig } = require('./config.js');
|
||||||
|
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function auth({ subject, action, resource }) {
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/auth'),
|
||||||
|
{ subject, action, resource },
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { auth };
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
let config = {};
|
||||||
|
let defaults = {};
|
||||||
|
|
||||||
|
function init(cfg, defaultOpts) {
|
||||||
|
config = { ...cfg };
|
||||||
|
if (defaultOpts) {
|
||||||
|
defaults = { ...defaultOpts };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaults() {
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefault(key) {
|
||||||
|
return defaults[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { init, getConfig, getDefaults, getDefault };
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig } = require('./config.js');
|
||||||
|
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDomains({ fedidUrl, auth: authPayload }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/entity/domains/get'),
|
||||||
|
{
|
||||||
|
fedidUrl: fedidUrl || cfg.fedidUrl,
|
||||||
|
auth: authPayload,
|
||||||
|
},
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createEntity({ fedidUrl, shortName }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/entity/create'),
|
||||||
|
{
|
||||||
|
fedidUrl: fedidUrl || cfg.fedidUrl,
|
||||||
|
shortName,
|
||||||
|
},
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getEntity({ shortName }) {
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/entity/get'),
|
||||||
|
{ shortName },
|
||||||
|
{ headers: _headers() },
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getDomains, getEntity, createEntity };
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
const axios = require('axios');
|
||||||
|
const { getConfig, getDefault } = require('./config.js');
|
||||||
|
|
||||||
|
function _getUrl(path) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
return `${cfg.apiUrl}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _headers(token) {
|
||||||
|
return {
|
||||||
|
'Authorization': `Bearer ${token || getConfig().apiKey}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function produceEvent({ type, senderShortName, recipientShortName, agreementId, meta, data, archive }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
const defaultArchive = { url: cfg.archiveUrl, key: cfg.archiveKey };
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/event/produce'),
|
||||||
|
{
|
||||||
|
type,
|
||||||
|
senderShortName,
|
||||||
|
recipientShortName,
|
||||||
|
agreementId: agreementId || getDefault('agreementId'),
|
||||||
|
meta,
|
||||||
|
data,
|
||||||
|
archive: archive || defaultArchive,
|
||||||
|
},
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getEvent({ eventId, meta }) {
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/event/get'),
|
||||||
|
{ eventId, meta },
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processEvent({ eventId, shortName, archive }) {
|
||||||
|
const cfg = getConfig();
|
||||||
|
const defaultArchive = { url: cfg.archiveUrl, key: cfg.archiveKey };
|
||||||
|
return (await axios.post(
|
||||||
|
_getUrl('/api/v1/data/event/process'),
|
||||||
|
{
|
||||||
|
eventId,
|
||||||
|
shortName,
|
||||||
|
archive: archive || defaultArchive,
|
||||||
|
},
|
||||||
|
{ headers: _headers() },
|
||||||
|
)).data;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { produceEvent, getEvent, processEvent };
|
||||||
+14
-262
@@ -1,263 +1,15 @@
|
|||||||
const axios = require("axios");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCConfig
|
|
||||||
* @property {boolean} [debug]
|
|
||||||
* @property {string} [systemPrefix]
|
|
||||||
* @property {string} [defaultAgreementId]
|
|
||||||
* @property {string|null} [domain]
|
|
||||||
* @property {string|null} [dataStoreApiUrl]
|
|
||||||
* @property {string|null} [dataStoreApiKey]
|
|
||||||
* @property {string|null} [archiveApiUrl]
|
|
||||||
* @property {string|null} [archiveApiKey]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCProduceEventData
|
|
||||||
* @property {string} [to]
|
|
||||||
* @property {string} [from]
|
|
||||||
* @property {string|null} [agreementId]
|
|
||||||
* @property {any} [payload]
|
|
||||||
* @property {any} [auth]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCProcessEventData
|
|
||||||
* @property {string} [to]
|
|
||||||
* @property {string} [eventId]
|
|
||||||
* @property {any} [auth]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCProduceAgreementData
|
|
||||||
* @property {Array<string>} [requiredSigners]
|
|
||||||
* @property {string} [signer]
|
|
||||||
* @property {string} [uri]
|
|
||||||
* @property {Array<string>} [purposes]
|
|
||||||
* @property {Array<string>} [caveats]
|
|
||||||
* @property {Array<string>} [validRoles]
|
|
||||||
* @property {string} [role]
|
|
||||||
* @property {any} [auth]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} JLINCProcessAgreementData
|
|
||||||
* @property {string} [agreementId]
|
|
||||||
* @property {string} [signer]
|
|
||||||
* @property {string} [role]
|
|
||||||
* @property {any} [auth]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCConfig} config - The configuration object for the library
|
|
||||||
*/
|
|
||||||
let config = {
|
|
||||||
debug: false,
|
|
||||||
systemPrefix: 'my-system',
|
|
||||||
defaultAgreementId: '00000000-0000-0000-0000-000000000000',
|
|
||||||
domain: null,
|
|
||||||
dataStoreApiUrl: null,
|
|
||||||
dataStoreApiKey: null,
|
|
||||||
archiveApiUrl: null,
|
|
||||||
archiveApiKey: null,
|
|
||||||
}
|
|
||||||
|
|
||||||
const entities = new Set();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} input
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function sanitize(input) {
|
|
||||||
return input.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} dir
|
|
||||||
* @param {any} payload
|
|
||||||
* @returns {Promise<any>}
|
|
||||||
*/
|
|
||||||
async function postToApi(dir, payload) {
|
|
||||||
const response = await axios.post(
|
|
||||||
`${config.dataStoreApiUrl}/api/v1/data/${dir}`,
|
|
||||||
payload,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
'Authorization': `Bearer ${config.dataStoreApiKey}`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} entityShortName
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
async function setEntity(name) {
|
|
||||||
const entityShortName = `${config.systemPrefix}-${sanitize(name)}@${config.domain}`;
|
|
||||||
if (!entities.has(entityShortName)) {
|
|
||||||
try {
|
|
||||||
await postToApi(`entity/get`, { shortName: entityShortName });
|
|
||||||
} catch (e) {
|
|
||||||
await postToApi(`entity/create`, { shortName: entityShortName });
|
|
||||||
}
|
|
||||||
entities.add(entityShortName);
|
|
||||||
}
|
|
||||||
return entityShortName
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCConfig} data - The configuration object for the application.
|
|
||||||
*/
|
|
||||||
function jlincInit(data) {
|
|
||||||
config = {
|
|
||||||
...config,
|
|
||||||
...data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getDomain() {
|
|
||||||
if (!config.domain) {
|
|
||||||
const domains = await postToApi(`entity/domains/get`, {});
|
|
||||||
config.domain = domains[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCProduceEventData} data - The data required for producing an event.
|
|
||||||
*/
|
|
||||||
async function jlincProduceEvent(data) {
|
|
||||||
let res = null;
|
|
||||||
try {
|
|
||||||
await getDomain();
|
|
||||||
const senderShortName = await setEntity(data.from)
|
|
||||||
const recipientShortName = await setEntity(data.to)
|
|
||||||
const agreementId = data.agreementId ?? config.defaultAgreementId;
|
|
||||||
const postData = {
|
|
||||||
type: 'data',
|
|
||||||
senderShortName,
|
|
||||||
recipientShortName,
|
|
||||||
agreementId,
|
|
||||||
data: data.payload,
|
|
||||||
archive: {
|
|
||||||
url: config.archiveApiUrl,
|
|
||||||
key: config.archiveApiKey,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (data.auth) postData.auth = data.auth;
|
|
||||||
res = await postToApi(`event/produce`, postData);
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(JSON.stringify({ res }, null, 2));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("[JLINC] Failed to produce event:", error.message);
|
|
||||||
if (config.debug) console.error(error)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCProcessEventData} data - The data required for processing an event.
|
|
||||||
*/
|
|
||||||
async function jlincProcessEvent(data) {
|
|
||||||
let res = null;
|
|
||||||
try {
|
|
||||||
await getDomain();
|
|
||||||
const shortName = await setEntity(data.to)
|
|
||||||
const postData = {
|
|
||||||
type: 'data',
|
|
||||||
shortName,
|
|
||||||
eventId: data.eventId,
|
|
||||||
archive: {
|
|
||||||
url: config.archiveApiUrl,
|
|
||||||
key: config.archiveApiKey,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (data.auth) postData.auth = data.auth;
|
|
||||||
res = await postToApi(`event/process`, postData);
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(JSON.stringify({ res }, null, 2));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("[JLINC] Failed to process event:", error.message);
|
|
||||||
if (config.debug) console.error(error)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCProduceAgreementData} data - The data required for producing an agreement.
|
|
||||||
*/
|
|
||||||
async function jlincProduceAgreement(data) {
|
|
||||||
let res = null;
|
|
||||||
try {
|
|
||||||
await getDomain();
|
|
||||||
const shortNames = [];
|
|
||||||
for (const id of data.requiredSigners) {
|
|
||||||
shortNames.push(await setEntity(id))
|
|
||||||
}
|
|
||||||
const shortName = await setEntity(data.signer)
|
|
||||||
const postData = {
|
|
||||||
data: {
|
|
||||||
uri: data.uri,
|
|
||||||
purposes: data.purposes,
|
|
||||||
caveats: data.caveats,
|
|
||||||
shortNames,
|
|
||||||
validRoles: data.validRoles,
|
|
||||||
},
|
|
||||||
shortName,
|
|
||||||
role: data.role,
|
|
||||||
archive: {
|
|
||||||
url: config.archiveApiUrl,
|
|
||||||
key: config.archiveApiKey,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (data.auth) postData.auth = data.auth;
|
|
||||||
res = await postToApi(`agreement/produce`, postData);
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(JSON.stringify({ res }, null, 2));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("[JLINC] Failed to produce agreement:", error.message);
|
|
||||||
if (config.debug) console.error(error)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {JLINCProcessAgreementData} data - The data required for processing an agreement.
|
|
||||||
*/
|
|
||||||
async function jlincProcessAgreement(data) {
|
|
||||||
let res = null;
|
|
||||||
try {
|
|
||||||
await getDomain();
|
|
||||||
const shortName = await setEntity(data.signer)
|
|
||||||
const postData = {
|
|
||||||
agreementId: data.agreementId,
|
|
||||||
shortName,
|
|
||||||
role: data.role,
|
|
||||||
archive: {
|
|
||||||
url: config.archiveApiUrl,
|
|
||||||
key: config.archiveApiKey,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (data.auth) postData.auth = data.auth;
|
|
||||||
res = await postToApi(`agreement/process`, postData);
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(JSON.stringify({ res }, null, 2));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("[JLINC] Failed to process agreement:", error.message);
|
|
||||||
if (config.debug) console.error(error)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
jlincInit,
|
init: require('./config.js').init,
|
||||||
jlincProduceEvent,
|
auth: require('./auth.js').auth,
|
||||||
jlincProcessEvent,
|
getDomains: require('./entity.js').getDomains,
|
||||||
jlincProduceAgreement,
|
getEntity: require('./entity.js').getEntity,
|
||||||
jlincProcessAgreement,
|
createEntity: require('./entity.js').createEntity,
|
||||||
}
|
produceAgreement: require('./agreement.js').produceAgreement,
|
||||||
|
processAgreement: require('./agreement.js').processAgreement,
|
||||||
|
getAgreement: require('./agreement.js').getAgreement,
|
||||||
|
produceEvent: require('./event.js').produceEvent,
|
||||||
|
getEvent: require('./event.js').getEvent,
|
||||||
|
processEvent: require('./event.js').processEvent,
|
||||||
|
getAudits: require('./audit.js').getAudits,
|
||||||
|
verifyAudit: require('./audit.js').verifyAudit,
|
||||||
|
};
|
||||||
+308
-165
@@ -1,183 +1,326 @@
|
|||||||
require('dotenv').config({ quiet: true })
|
const axios = require('axios');
|
||||||
const {
|
const jlinc = require('./index');
|
||||||
jlincInit,
|
|
||||||
jlincProduceEvent,
|
|
||||||
jlincProcessEvent,
|
|
||||||
jlincProduceAgreement,
|
|
||||||
jlincProcessAgreement,
|
|
||||||
} = require("./index.js");
|
|
||||||
|
|
||||||
const printResults = false;
|
jest.mock('axios');
|
||||||
|
|
||||||
function printResult(data) {
|
const mockedAxios = axios;
|
||||||
if (printResults) {
|
|
||||||
console.log(`Result`);
|
|
||||||
console.log("---------------------------------------------");
|
|
||||||
console.log(JSON.stringify(data, null, 2));
|
|
||||||
console.log("---------------------------------------------");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateRandomString(length) {
|
const mockResponse = (data) => ({ data });
|
||||||
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
const mockPost = jest.fn();
|
||||||
let result = "";
|
|
||||||
const charactersLength = characters.length;
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
beforeEach(() => {
|
||||||
const config = {
|
jest.clearAllMocks();
|
||||||
dataStoreApiUrl: process.env.JLINC_DATA_STORE_API_URL ?? "http://localhost:9090",
|
mockedAxios.post = mockPost;
|
||||||
dataStoreApiKey: process.env.JLINC_DATA_STORE_API_KEY,
|
mockPost.mockImplementation((url, data, config) => Promise.resolve(mockResponse({ ok: true, url, data, config })));
|
||||||
archiveApiUrl: process.env.JLINC_ARCHIVE_API_URL ?? "http://localhost:9090",
|
|
||||||
archiveApiKey: process.env.JLINC_ARCHIVE_API_KEY,
|
|
||||||
defaultAgreementId: "00000000-0000-0000-0000-000000000000",
|
|
||||||
systemPrefix: process.env.JLINC_SYSTEM_PREFIX ?? "TestJlinc",
|
|
||||||
debug: false,
|
|
||||||
}
|
|
||||||
jlincInit(config);
|
|
||||||
|
|
||||||
try {
|
jlinc.init(
|
||||||
|
{
|
||||||
|
apiKey: 'test-api-key',
|
||||||
|
apiUrl: 'http://localhost:9090',
|
||||||
|
archiveUrl: 'http://localhost:9090',
|
||||||
|
archiveKey: 'test-archive-key',
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
},
|
||||||
|
{ agreementId: 'default-agreement-id' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
describe("JLINC transaction", () => {
|
describe('auth', () => {
|
||||||
let data;
|
it('should POST to /api/v1/auth with correct payload and headers', async () => {
|
||||||
let r;
|
const subject = { type: 'user', id: 'tester' };
|
||||||
let agreementId;
|
const action = { name: 'read' };
|
||||||
let eventId;
|
const resource = { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } };
|
||||||
|
|
||||||
// Define participants
|
await jlinc.auth({ subject, action, resource });
|
||||||
const p1 = generateRandomString(11);
|
|
||||||
const p2 = generateRandomString(11);
|
|
||||||
|
|
||||||
it(`Produce (create and sign) agreement`, async () => {
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
data = {
|
'http://localhost:9090/api/v1/auth',
|
||||||
uri: 'http://localhost:9090/agreements/05c93a30cc699cfaee9185f23a5f68ffb12305acce1ca4b9444758fc4d594828',
|
{ subject, action, resource },
|
||||||
validRoles: ['provider', 'user'],
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
purposes: ['testing'],
|
);
|
||||||
caveats: ['production'],
|
});
|
||||||
requiredSigners: [p1],
|
});
|
||||||
signer: p1,
|
|
||||||
|
describe('getDomains', () => {
|
||||||
|
it('should POST to /api/v1/data/entity/domains/get with fedidUrl and auth', async () => {
|
||||||
|
const authPayload = { subject: { type: 'user', id: 'tester' }, action: { name: 'read' }, resource: { type: 'data', id: '1234' } };
|
||||||
|
|
||||||
|
await jlinc.getDomains({ fedidUrl: 'http://fedid.test', auth: authPayload });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/entity/domains/get',
|
||||||
|
{ fedidUrl: 'http://fedid.test', auth: authPayload },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use default fedidUrl from config when not provided', async () => {
|
||||||
|
const authPayload = { subject: { type: 'user', id: 'tester' }, action: { name: 'read' }, resource: { type: 'data', id: '1234' } };
|
||||||
|
|
||||||
|
await jlinc.getDomains({ auth: authPayload });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/entity/domains/get',
|
||||||
|
{ fedidUrl: 'http://localhost:8881', auth: authPayload },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getEntity', () => {
|
||||||
|
it('should POST to /api/v1/data/entity/get with shortName', async () => {
|
||||||
|
await jlinc.getEntity({ shortName: 'test-entity@test.domain' });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/entity/get',
|
||||||
|
{ shortName: 'test-entity@test.domain' },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createEntity', () => {
|
||||||
|
it('should POST to /api/v1/data/entity/create with correct payload', async () => {
|
||||||
|
const shortName = 'test-entity';
|
||||||
|
|
||||||
|
await jlinc.createEntity({ fedidUrl: 'http://fedid.test', shortName });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/entity/create',
|
||||||
|
{ fedidUrl: 'http://fedid.test', shortName },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use default fedidUrl from config when not provided', async () => {
|
||||||
|
const shortName = 'test-entity';
|
||||||
|
|
||||||
|
await jlinc.createEntity({ shortName });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/entity/create',
|
||||||
|
{ fedidUrl: 'http://localhost:8881', shortName },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('produceAgreement', () => {
|
||||||
|
it('should POST to /api/v1/data/agreement/produce with correct payload and default archive', async () => {
|
||||||
|
const params = {
|
||||||
|
data: { references: ['ref1'], permitted: ['read'] },
|
||||||
|
shortName: 'provider',
|
||||||
role: 'provider',
|
role: 'provider',
|
||||||
}
|
};
|
||||||
r = await jlincProduceAgreement(data)
|
|
||||||
expect(r).toBeDefined();
|
|
||||||
printResult(r);
|
|
||||||
expect(r.created && r.processed).toBeDefined();
|
|
||||||
agreementId = r.created.agreementId
|
|
||||||
})
|
|
||||||
|
|
||||||
it(`Process (cross sign) agreement`, async () => {
|
await jlinc.produceAgreement(params);
|
||||||
data = {
|
|
||||||
agreementId,
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
signer: p2,
|
'http://localhost:9090/api/v1/data/agreement/produce',
|
||||||
|
{
|
||||||
|
...params,
|
||||||
|
archive: { url: 'http://localhost:9090', key: 'test-archive-key' },
|
||||||
|
},
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use provided archive override', async () => {
|
||||||
|
const params = {
|
||||||
|
data: { references: ['ref1'] },
|
||||||
|
shortName: 'provider',
|
||||||
|
role: 'provider',
|
||||||
|
archive: { url: 'http://custom', key: 'custom-key' },
|
||||||
|
};
|
||||||
|
|
||||||
|
await jlinc.produceAgreement(params);
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/agreement/produce',
|
||||||
|
{ ...params, archive: { url: 'http://custom', key: 'custom-key' } },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('processAgreement', () => {
|
||||||
|
it('should POST to /api/v1/data/agreement/process with correct payload', async () => {
|
||||||
|
await jlinc.processAgreement({ agreementId: 'agr-1', shortName: 'user', role: 'user' });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/agreement/process',
|
||||||
|
{
|
||||||
|
agreementId: 'agr-1',
|
||||||
|
shortName: 'user',
|
||||||
role: 'user',
|
role: 'user',
|
||||||
}
|
archive: { url: 'http://localhost:9090', key: 'test-archive-key' },
|
||||||
r = await jlincProcessAgreement(data)
|
},
|
||||||
expect(r).toBeDefined();
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
printResult(r);
|
);
|
||||||
expect(r.auditData).toBeDefined();
|
});
|
||||||
expect(r.auditData.audit.agreementId === agreementId).toBe(true);
|
|
||||||
})
|
|
||||||
|
|
||||||
it(`Produce (create and sign) event for data to be sent`, async () => {
|
it('should fall back to default agreementId when not provided', async () => {
|
||||||
data = {
|
await jlinc.processAgreement({ shortName: 'user', role: 'user' });
|
||||||
from: p1,
|
|
||||||
to: p2,
|
|
||||||
agreementId,
|
|
||||||
payload: {
|
|
||||||
data: "testing",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r = await jlincProduceEvent(data)
|
|
||||||
expect(r).toBeDefined();
|
|
||||||
printResult(r);
|
|
||||||
expect(r.created && r.processed).toBeDefined();
|
|
||||||
expect(r.created.agreementId === agreementId).toBe(true);
|
|
||||||
eventId = r.created.eventId;
|
|
||||||
})
|
|
||||||
|
|
||||||
it(`Process (sign) by the receiver after data is received`, async () => {
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
data = {
|
expect.any(String),
|
||||||
to: p2,
|
expect.objectContaining({ agreementId: 'default-agreement-id' }),
|
||||||
eventId,
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
}
|
);
|
||||||
r = await jlincProcessEvent(data)
|
});
|
||||||
expect(r).toBeDefined();
|
});
|
||||||
printResult(r);
|
|
||||||
expect(r.auditData).toBeDefined();
|
|
||||||
expect(r.auditData.audit.eventId === eventId).toBe(true);
|
|
||||||
})
|
|
||||||
|
|
||||||
it(`Produce (create and sign) event for data to be sent with successful auth`, async () => {
|
describe('getAgreement', () => {
|
||||||
data = {
|
it('should POST to /api/v1/data/agreement/get with correct payload', async () => {
|
||||||
from: p1,
|
await jlinc.getAgreement({ agreementId: 'agr-1', includeSignatures: true });
|
||||||
to: p2,
|
|
||||||
auth: {
|
|
||||||
subject: {
|
|
||||||
type: "user",
|
|
||||||
id: "tester",
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
name: "read",
|
|
||||||
},
|
|
||||||
resource: {
|
|
||||||
type: "data",
|
|
||||||
id: "1234",
|
|
||||||
properties: {
|
|
||||||
ownerID: "tester@test.com",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
payload: {
|
|
||||||
data: "testing",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r = await jlincProduceEvent(data)
|
|
||||||
expect(r).toBeDefined();
|
|
||||||
printResult(r);
|
|
||||||
expect(r.created && r.processed).toBeDefined();
|
|
||||||
expect(r.created.agreementId === config.defaultAgreementId).toBe(true);
|
|
||||||
})
|
|
||||||
|
|
||||||
it(`Produce (create and sign) event for data to be sent with failed auth`, async () => {
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
data = {
|
'http://localhost:9090/api/v1/data/agreement/get',
|
||||||
from: p1,
|
{ agreementId: 'agr-1', includeSignatures: true },
|
||||||
to: p2,
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
auth: {
|
);
|
||||||
subject: {
|
});
|
||||||
type: "user",
|
|
||||||
id: "tester",
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
name: "write",
|
|
||||||
},
|
|
||||||
resource: {
|
|
||||||
type: "data",
|
|
||||||
id: "1234",
|
|
||||||
properties: {
|
|
||||||
ownerID: "tester@test.com",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
payload: {
|
|
||||||
data: "testing",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r = await jlincProduceEvent(data)
|
|
||||||
expect(r).toBeDefined();
|
|
||||||
printResult(r);
|
|
||||||
expect(r.decision).toBeDefined();
|
|
||||||
expect(r.decision).toBe(false);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
} catch (err) {
|
it('should fall back to default agreementId when not provided', async () => {
|
||||||
console.error("[*] ERROR:", err);
|
await jlinc.getAgreement({ includeSignatures: true });
|
||||||
}
|
|
||||||
|
|
||||||
}
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
expect.any(String),
|
||||||
|
expect.objectContaining({ agreementId: 'default-agreement-id' }),
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
main()
|
describe('produceEvent', () => {
|
||||||
|
it('should POST to /api/v1/data/event/produce with correct payload and default archive', async () => {
|
||||||
|
const params = {
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: 'user1',
|
||||||
|
recipientShortName: 'provider1',
|
||||||
|
agreementId: 'agr-1',
|
||||||
|
meta: { id: '123' },
|
||||||
|
data: { query: 'test' },
|
||||||
|
};
|
||||||
|
|
||||||
|
await jlinc.produceEvent(params);
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/event/produce',
|
||||||
|
{ ...params, archive: { url: 'http://localhost:9090', key: 'test-archive-key' } },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fall back to default agreementId when not provided', async () => {
|
||||||
|
await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: 'user1',
|
||||||
|
recipientShortName: 'provider1',
|
||||||
|
meta: {},
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
expect.any(String),
|
||||||
|
expect.objectContaining({ agreementId: 'default-agreement-id' }),
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getEvent', () => {
|
||||||
|
it('should POST to /api/v1/data/event/get with eventId', async () => {
|
||||||
|
await jlinc.getEvent({ eventId: 'evt-1' });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/event/get',
|
||||||
|
{ eventId: 'evt-1', meta: undefined },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should POST to /api/v1/data/event/get with meta filter', async () => {
|
||||||
|
await jlinc.getEvent({ meta: { id: '123' } });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/event/get',
|
||||||
|
{ eventId: undefined, meta: { id: '123' } },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('processEvent', () => {
|
||||||
|
it('should POST to /api/v1/data/event/process with correct payload and default archive', async () => {
|
||||||
|
await jlinc.processEvent({ eventId: 'evt-1', shortName: 'provider' });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/event/process',
|
||||||
|
{
|
||||||
|
eventId: 'evt-1',
|
||||||
|
shortName: 'provider',
|
||||||
|
archive: { url: 'http://localhost:9090', key: 'test-archive-key' },
|
||||||
|
},
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getAudits', () => {
|
||||||
|
it('should POST to /api/v1/audit/get with correct payload and archive auth', async () => {
|
||||||
|
await jlinc.getAudits({ agreementId: 'agr-1' });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/audit/get',
|
||||||
|
{ agreementId: 'agr-1', eventId: undefined, meta: undefined },
|
||||||
|
{ headers: { Authorization: 'Bearer test-archive-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fall back to default agreementId when not provided', async () => {
|
||||||
|
await jlinc.getAudits({ eventId: 'evt-1' });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
expect.any(String),
|
||||||
|
expect.objectContaining({ agreementId: 'default-agreement-id' }),
|
||||||
|
{ headers: { Authorization: 'Bearer test-archive-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use archiveKey from config for auth header', async () => {
|
||||||
|
await jlinc.getAudits({ eventId: 'evt-1' });
|
||||||
|
|
||||||
|
const callArgs = mockPost.mock.calls[0];
|
||||||
|
const headers = callArgs[2].headers;
|
||||||
|
expect(headers.Authorization).toBe('Bearer test-archive-key');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('verifyAudit', () => {
|
||||||
|
it('should POST to /api/v1/data/audit/verify with correct payload', async () => {
|
||||||
|
await jlinc.verifyAudit({ audits: ['a1', 'a2'], shortNames: ['s1', 's2'] });
|
||||||
|
|
||||||
|
expect(mockPost).toHaveBeenCalledWith(
|
||||||
|
'http://localhost:9090/api/v1/data/audit/verify',
|
||||||
|
{ audits: ['a1', 'a2'], shortNames: ['s1', 's2'] },
|
||||||
|
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('config defaults', () => {
|
||||||
|
it('should use default agreementId from init second argument', async () => {
|
||||||
|
await jlinc.getAgreement({});
|
||||||
|
|
||||||
|
const callArgs = mockPost.mock.calls[0];
|
||||||
|
expect(callArgs[1].agreementId).toBe('default-agreement-id');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow overriding default agreementId per-call', async () => {
|
||||||
|
await jlinc.getAgreement({ agreementId: 'override-id' });
|
||||||
|
|
||||||
|
const callArgs = mockPost.mock.calls[0];
|
||||||
|
expect(callArgs[1].agreementId).toBe('override-id');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { init, getConfig, getDefaults, getDefault } from './config.js';
|
||||||
@@ -0,0 +1,312 @@
|
|||||||
|
require('dotenv').config({ path: require('path').resolve(__dirname, '../.env') });
|
||||||
|
const jlinc = require('../index');
|
||||||
|
|
||||||
|
jlinc.init({
|
||||||
|
apiKey: process.env.JLINC_API_KEY,
|
||||||
|
apiUrl: process.env.JLINC_API_URL,
|
||||||
|
archiveUrl: process.env.JLINC_ARCHIVE_URL,
|
||||||
|
archiveKey: process.env.JLINC_ARCHIVE_KEY,
|
||||||
|
fedidUrl: process.env.JLINC_FEDID_URL,
|
||||||
|
});
|
||||||
|
|
||||||
|
let domain;
|
||||||
|
let provider;
|
||||||
|
let user;
|
||||||
|
let agreementId;
|
||||||
|
let agreement;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const domains = await jlinc.getDomains({
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
auth: {
|
||||||
|
subject: { type: 'user', id: 'tester' },
|
||||||
|
action: { name: 'read' },
|
||||||
|
resource: { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
domain = domains[0];
|
||||||
|
|
||||||
|
provider = await jlinc.createEntity({
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
shortName: `provider-integ-${Date.now()}@${domain}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
user = await jlinc.createEntity({
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
shortName: `user-integ-${Date.now()}@${domain}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
agreement = await jlinc.produceAgreement({
|
||||||
|
data: {
|
||||||
|
references: ['https://sisa.jlinc.org/v1/34020c5fb59ebc6507ebca4eb38090aec1097c6aec8d2ae2250ddfed4b4aa63c'],
|
||||||
|
permitted: ['data-sharing'],
|
||||||
|
prohibited: ['non-delegable'],
|
||||||
|
shortNames: [provider.didDoc.shortName],
|
||||||
|
validRoles: ['provider', 'user', 'third-party'],
|
||||||
|
},
|
||||||
|
shortName: provider.didDoc.shortName,
|
||||||
|
role: 'provider',
|
||||||
|
});
|
||||||
|
agreementId = agreement.created.agreementId;
|
||||||
|
|
||||||
|
await jlinc.processAgreement({
|
||||||
|
agreementId,
|
||||||
|
shortName: user.didDoc.shortName,
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('JLINC API Integration Tests', () => {
|
||||||
|
describe('auth', () => {
|
||||||
|
it('should authenticate successfully with read action', async () => {
|
||||||
|
const result = await jlinc.auth({
|
||||||
|
subject: { type: 'user', id: 'tester' },
|
||||||
|
action: { name: 'read' },
|
||||||
|
resource: { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } },
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject authentication with write action', async () => {
|
||||||
|
const result = await jlinc.auth({
|
||||||
|
subject: { type: 'user', id: 'tester' },
|
||||||
|
action: { name: 'write' },
|
||||||
|
resource: { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } },
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('domains', () => {
|
||||||
|
it('should get available domains', async () => {
|
||||||
|
const domains = await jlinc.getDomains({
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
auth: {
|
||||||
|
subject: { type: 'user', id: 'tester' },
|
||||||
|
action: { name: 'read' },
|
||||||
|
resource: { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(domains).toBeDefined();
|
||||||
|
expect(Array.isArray(domains)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('entity creation', () => {
|
||||||
|
it('should create a provider entity', async () => {
|
||||||
|
expect(provider).toBeDefined();
|
||||||
|
expect(provider.didDoc).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a user entity', async () => {
|
||||||
|
expect(user).toBeDefined();
|
||||||
|
expect(user.didDoc).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('entity retrieval', () => {
|
||||||
|
it('should get a provider entity by shortName', async () => {
|
||||||
|
const result = await jlinc.getEntity({ shortName: provider.didDoc.shortName });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result.data).toBeDefined();
|
||||||
|
expect(result.data.didDoc).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get a user entity by shortName', async () => {
|
||||||
|
const result = await jlinc.getEntity({ shortName: user.didDoc.shortName });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result.data).toBeDefined();
|
||||||
|
expect(result.data.didDoc).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('agreement lifecycle', () => {
|
||||||
|
it('should produce an agreement', async () => {
|
||||||
|
expect(agreement).toBeDefined();
|
||||||
|
expect(agreement.created).toBeDefined();
|
||||||
|
expect(agreementId).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should process (cross-sign) the agreement as user', async () => {
|
||||||
|
const result = await jlinc.processAgreement({
|
||||||
|
agreementId,
|
||||||
|
shortName: user.didDoc.shortName,
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get the agreement', async () => {
|
||||||
|
const result = await jlinc.getAgreement({ agreementId, includeSignatures: true });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('event lifecycle', () => {
|
||||||
|
it('should produce an event', async () => {
|
||||||
|
const result = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: `integration-test-${Date.now()}` },
|
||||||
|
data: { query: 'Why am I making this?' },
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result.created).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get an event by eventId', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: `get-event-test-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getEvent({ eventId: event.created.eventId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get an event by meta ID', async () => {
|
||||||
|
const metaId = `meta-test-${Date.now()}`;
|
||||||
|
await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: metaId },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getEvent({ meta: { myCustomId: metaId } });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should process an event as provider', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: `process-test-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.processEvent({
|
||||||
|
eventId: event.created.eventId,
|
||||||
|
shortName: provider.didDoc.shortName,
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('audit', () => {
|
||||||
|
it('should get agreement audits', async () => {
|
||||||
|
const result = await jlinc.getAudits({ agreementId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get event audits by eventId', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: `audit-event-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getAudits({ eventId: event.created.eventId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get event audits by meta ID', async () => {
|
||||||
|
const metaId = `audit-meta-${Date.now()}`;
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: metaId },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getAudits({ meta: { myCustomId: metaId } });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should verify audit records', async () => {
|
||||||
|
const audits = await jlinc.getAudits({ agreementId });
|
||||||
|
|
||||||
|
const result = await jlinc.verifyAudit({
|
||||||
|
audits: audits.auditRecords || [],
|
||||||
|
shortNames: [user.didDoc.shortName, provider.didDoc.shortName],
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('nil agreement events', () => {
|
||||||
|
it('should produce an event under the nil agreement', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId: '00000000-0000-0000-0000-000000000000',
|
||||||
|
meta: { myCustomId: `nil-test-${Date.now()}` },
|
||||||
|
data: { query: 'Why am I making this?' },
|
||||||
|
});
|
||||||
|
expect(event).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get a nil agreement event by eventId', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId: '00000000-0000-0000-0000-000000000000',
|
||||||
|
meta: { myCustomId: `nil-get-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getEvent({ eventId: event.created.eventId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get nil agreement event audits', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId: '00000000-0000-0000-0000-000000000000',
|
||||||
|
meta: { myCustomId: `nil-audit-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getAudits({ eventId: event.created.eventId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should verify nil agreement audit', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId: '00000000-0000-0000-0000-000000000000',
|
||||||
|
meta: { myCustomId: `nil-verify-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const audits = await jlinc.getAudits({ eventId: event.created.eventId });
|
||||||
|
|
||||||
|
const result = await jlinc.verifyAudit({
|
||||||
|
audits: audits.auditRecords || [],
|
||||||
|
shortNames: [user.didDoc.shortName, provider.didDoc.shortName],
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,310 @@
|
|||||||
|
require('dotenv').config({ path: require('path').resolve(__dirname, '../.env') });
|
||||||
|
const jlinc = require('../index');
|
||||||
|
|
||||||
|
jlinc.init({
|
||||||
|
apiKey: process.env.JLINC_API_KEY,
|
||||||
|
apiUrl: process.env.JLINC_API_URL,
|
||||||
|
archiveUrl: process.env.JLINC_ARCHIVE_URL,
|
||||||
|
archiveKey: process.env.JLINC_ARCHIVE_KEY,
|
||||||
|
fedidUrl: process.env.JLINC_FEDID_URL,
|
||||||
|
});
|
||||||
|
|
||||||
|
let domain: string;
|
||||||
|
let provider: any;
|
||||||
|
let user: any;
|
||||||
|
let agreementId: string;
|
||||||
|
let agreement: any;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const domains = await jlinc.getDomains({
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
auth: {
|
||||||
|
subject: { type: 'user', id: 'tester' },
|
||||||
|
action: { name: 'read' },
|
||||||
|
resource: { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
domain = domains[0];
|
||||||
|
|
||||||
|
provider = await jlinc.createEntity({
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
shortName: `provider-integ-${Date.now()}@${domain}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
user = await jlinc.createEntity({
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
shortName: `user-integ-${Date.now()}@${domain}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
agreement = await jlinc.produceAgreement({
|
||||||
|
data: {
|
||||||
|
references: ['https://sisa.jlinc.org/v1/34020c5fb59ebc6507ebca4eb38090aec1097c6aec8d2ae2250ddfed4b4aa63c'],
|
||||||
|
permitted: ['data-sharing'],
|
||||||
|
prohibited: ['non-delegable'],
|
||||||
|
shortNames: [provider.didDoc.shortName],
|
||||||
|
validRoles: ['provider', 'user', 'third-party'],
|
||||||
|
},
|
||||||
|
shortName: provider.didDoc.shortName,
|
||||||
|
role: 'provider',
|
||||||
|
});
|
||||||
|
agreementId = agreement.created.agreementId;
|
||||||
|
|
||||||
|
await jlinc.processAgreement({
|
||||||
|
agreementId,
|
||||||
|
shortName: user.didDoc.shortName,
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('JLINC API Integration Tests', () => {
|
||||||
|
describe('auth', () => {
|
||||||
|
it('should authenticate successfully with read action', async () => {
|
||||||
|
const result = await jlinc.auth({
|
||||||
|
subject: { type: 'user', id: 'tester' },
|
||||||
|
action: { name: 'read' },
|
||||||
|
resource: { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } },
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject authentication with write action', async () => {
|
||||||
|
const result = await jlinc.auth({
|
||||||
|
subject: { type: 'user', id: 'tester' },
|
||||||
|
action: { name: 'write' },
|
||||||
|
resource: { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } },
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('domains', () => {
|
||||||
|
it('should get available domains', async () => {
|
||||||
|
const domains = await jlinc.getDomains({
|
||||||
|
fedidUrl: 'http://localhost:8881',
|
||||||
|
auth: {
|
||||||
|
subject: { type: 'user', id: 'tester' },
|
||||||
|
action: { name: 'read' },
|
||||||
|
resource: { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(domains).toBeDefined();
|
||||||
|
expect(Array.isArray(domains)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('entity creation', () => {
|
||||||
|
it('should create a provider entity', async () => {
|
||||||
|
expect(provider).toBeDefined();
|
||||||
|
expect(provider.didDoc).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a user entity', async () => {
|
||||||
|
expect(user).toBeDefined();
|
||||||
|
expect(user.didDoc).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('entity retrieval', () => {
|
||||||
|
it('should get a provider entity by shortName', async () => {
|
||||||
|
const result = await jlinc.getEntity({ shortName: provider.didDoc.shortName });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result.data.didDoc).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get a user entity by shortName', async () => {
|
||||||
|
const result = await jlinc.getEntity({ shortName: user.didDoc.shortName });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result.data.didDoc).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('agreement lifecycle', () => {
|
||||||
|
it('should produce an agreement', async () => {
|
||||||
|
expect(agreement).toBeDefined();
|
||||||
|
expect(agreement.created).toBeDefined();
|
||||||
|
expect(agreementId).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should process (cross-sign) the agreement as user', async () => {
|
||||||
|
const result = await jlinc.processAgreement({
|
||||||
|
agreementId,
|
||||||
|
shortName: user.didDoc.shortName,
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get the agreement', async () => {
|
||||||
|
const result = await jlinc.getAgreement({ agreementId, includeSignatures: true });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('event lifecycle', () => {
|
||||||
|
it('should produce an event', async () => {
|
||||||
|
const result = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: `integration-test-${Date.now()}` },
|
||||||
|
data: { query: 'Why am I making this?' },
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result.created).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get an event by eventId', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: `get-event-test-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getEvent({ eventId: event.created.eventId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get an event by meta ID', async () => {
|
||||||
|
const metaId = `meta-test-${Date.now()}`;
|
||||||
|
await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: metaId },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getEvent({ meta: { myCustomId: metaId } });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should process an event as provider', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: `process-test-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.processEvent({
|
||||||
|
eventId: event.created.eventId,
|
||||||
|
shortName: provider.didDoc.shortName,
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('audit', () => {
|
||||||
|
it('should get agreement audits', async () => {
|
||||||
|
const result = await jlinc.getAudits({ agreementId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get event audits by eventId', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: `audit-event-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getAudits({ eventId: event.created.eventId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get event audits by meta ID', async () => {
|
||||||
|
const metaId = `audit-meta-${Date.now()}`;
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId,
|
||||||
|
meta: { myCustomId: metaId },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getAudits({ meta: { myCustomId: metaId } });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should verify audit records', async () => {
|
||||||
|
const audits = await jlinc.getAudits({ agreementId });
|
||||||
|
|
||||||
|
const result = await jlinc.verifyAudit({
|
||||||
|
audits: audits.auditRecords || [],
|
||||||
|
shortNames: [user.didDoc.shortName, provider.didDoc.shortName],
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('nil agreement events', () => {
|
||||||
|
it('should produce an event under the nil agreement', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId: '00000000-0000-0000-0000-000000000000',
|
||||||
|
meta: { myCustomId: `nil-test-${Date.now()}` },
|
||||||
|
data: { query: 'Why am I making this?' },
|
||||||
|
});
|
||||||
|
expect(event).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get a nil agreement event by eventId', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId: '00000000-0000-0000-0000-000000000000',
|
||||||
|
meta: { myCustomId: `nil-get-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getEvent({ eventId: event.created.eventId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get nil agreement event audits', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId: '00000000-0000-0000-0000-000000000000',
|
||||||
|
meta: { myCustomId: `nil-audit-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await jlinc.getAudits({ eventId: event.created.eventId });
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should verify nil agreement audit', async () => {
|
||||||
|
const event = await jlinc.produceEvent({
|
||||||
|
type: 'data',
|
||||||
|
senderShortName: user.didDoc.shortName,
|
||||||
|
recipientShortName: provider.didDoc.shortName,
|
||||||
|
agreementId: '00000000-0000-0000-0000-000000000000',
|
||||||
|
meta: { myCustomId: `nil-verify-${Date.now()}` },
|
||||||
|
data: { query: 'test' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const audits = await jlinc.getAudits({ eventId: event.created.eventId });
|
||||||
|
|
||||||
|
const result = await jlinc.verifyAudit({
|
||||||
|
audits: audits.auditRecords || [],
|
||||||
|
shortNames: [user.didDoc.shortName, provider.didDoc.shortName],
|
||||||
|
});
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
const jlinc = require('./index.js');
|
||||||
|
module.exports = jlinc;
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
declare const _exports: {
|
||||||
|
init: (cfg: object, defaultOpts?: object) => void;
|
||||||
|
auth: (params: { subject: any; action: any; resource: any }) => Promise<any>;
|
||||||
|
getDomains: (params: { fedidUrl?: string; auth?: any }) => Promise<any>;
|
||||||
|
getEntity: (params: { shortName: string }) => Promise<any>;
|
||||||
|
createEntity: (params: { fedidUrl?: string; shortName: string }) => Promise<any>;
|
||||||
|
produceAgreement: (params: { data: any; shortName: string; role: string; archive?: any }) => Promise<any>;
|
||||||
|
processAgreement: (params: { agreementId?: string; shortName: string; role: string; archive?: any }) => Promise<any>;
|
||||||
|
getAgreement: (params: { agreementId?: string; includeSignatures?: boolean }) => Promise<any>;
|
||||||
|
produceEvent: (params: { type: string; senderShortName: string; recipientShortName: string; agreementId?: string; meta?: any; data: any; archive?: any }) => Promise<any>;
|
||||||
|
getEvent: (params: { eventId?: string; meta?: any }) => Promise<any>;
|
||||||
|
processEvent: (params: { eventId: string; shortName: string; archive?: any }) => Promise<any>;
|
||||||
|
getAudits: (params: { agreementId?: string; eventId?: string; meta?: any }) => Promise<any>;
|
||||||
|
verifyAudit: (params: { audits: string[]; shortNames: string[] }) => Promise<any>;
|
||||||
|
};
|
||||||
|
export = _exports;
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
export function init(cfg: object, defaultOpts?: object): void;
|
||||||
|
export function auth(params: { subject: any; action: any; resource: any }): Promise<any>;
|
||||||
|
export function getDomains(params: { fedidUrl?: string; auth?: any }): Promise<any>;
|
||||||
|
export function getEntity(params: { shortName: string }): Promise<any>;
|
||||||
|
export function createEntity(params: { fedidUrl?: string; shortName: string }): Promise<any>;
|
||||||
|
export function produceAgreement(params: { data: any; shortName: string; role: string; archive?: any }): Promise<any>;
|
||||||
|
export function processAgreement(params: { agreementId?: string; shortName: string; role: string; archive?: any }): Promise<any>;
|
||||||
|
export function getAgreement(params: { agreementId?: string; includeSignatures?: boolean }): Promise<any>;
|
||||||
|
export function produceEvent(params: { type: string; senderShortName: string; recipientShortName: string; agreementId?: string; meta?: any; data: any; archive?: any }): Promise<any>;
|
||||||
|
export function getEvent(params: { eventId?: string; meta?: any }): Promise<any>;
|
||||||
|
export function processEvent(params: { eventId: string; shortName: string; archive?: any }): Promise<any>;
|
||||||
|
export function getAudits(params: { agreementId?: string; eventId?: string; meta?: any }): Promise<any>;
|
||||||
|
export function verifyAudit(params: { audits: string[]; shortNames: string[] }): Promise<any>;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import jlinc from './index.js';
|
||||||
|
|
||||||
|
export const { init, getConfig, getDefaults, getDefault } = jlinc;
|
||||||
|
export const { auth } = jlinc;
|
||||||
|
export const { getDomains, getEntity, createEntity } = jlinc;
|
||||||
|
export const { produceAgreement, processAgreement, getAgreement } = jlinc;
|
||||||
|
export const { produceEvent, getEvent, processEvent } = jlinc;
|
||||||
|
export const { getAudits, verifyAudit } = jlinc;
|
||||||
|
export default jlinc;
|
||||||
-219
@@ -1,219 +0,0 @@
|
|||||||
require('dotenv').config({ quiet: true })
|
|
||||||
const {
|
|
||||||
jlincInit,
|
|
||||||
jlincProduceEvent,
|
|
||||||
jlincProcessEvent,
|
|
||||||
jlincProduceAgreement,
|
|
||||||
jlincProcessAgreement,
|
|
||||||
} = require("../src/index.js");
|
|
||||||
|
|
||||||
const printResults = true;
|
|
||||||
|
|
||||||
function generateRandomString(length) {
|
|
||||||
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
let result = "";
|
|
||||||
const charactersLength = characters.length;
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
const config = {
|
|
||||||
dataStoreApiUrl: process.env.JLINC_DATA_STORE_API_URL ?? "http://localhost:9090",
|
|
||||||
dataStoreApiKey: process.env.JLINC_DATA_STORE_API_KEY,
|
|
||||||
archiveApiUrl: process.env.JLINC_ARCHIVE_API_URL ?? "http://localhost:9090",
|
|
||||||
archiveApiKey: process.env.JLINC_ARCHIVE_API_KEY,
|
|
||||||
defaultAgreementId: "00000000-0000-0000-0000-000000000000",
|
|
||||||
systemPrefix: process.env.JLINC_SYSTEM_PREFIX ?? "TestJlinc",
|
|
||||||
debug: false,
|
|
||||||
}
|
|
||||||
jlincInit(config);
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
let data;
|
|
||||||
let r;
|
|
||||||
|
|
||||||
// Define participants
|
|
||||||
const entity1 = generateRandomString(11);
|
|
||||||
const entity2 = generateRandomString(11);
|
|
||||||
|
|
||||||
console.log(`\nAction: Produce (create and sign) agreement`)
|
|
||||||
data = {
|
|
||||||
uri: 'http://localhost:9090/agreements/05c93a30cc699cfaee9185f23a5f68ffb12305acce1ca4b9444758fc4d594828',
|
|
||||||
validRoles: ['provider', 'user'],
|
|
||||||
purposes: ['testing'],
|
|
||||||
caveats: ['production'],
|
|
||||||
requiredSigners: [entity1],
|
|
||||||
signer: entity1,
|
|
||||||
role: 'provider',
|
|
||||||
}
|
|
||||||
r = await jlincProduceAgreement(data)
|
|
||||||
if (r) {
|
|
||||||
if (printResults) {
|
|
||||||
console.log(`Result:`)
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
console.log(JSON.stringify(r, null, 2))
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
}
|
|
||||||
if (r.created && r.processed) {
|
|
||||||
console.log('PASS')
|
|
||||||
} else {
|
|
||||||
throw new Error('FAIL')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const agreementId = r.created.agreementId
|
|
||||||
|
|
||||||
console.log(`\nAction: Process (cross sign) agreement`)
|
|
||||||
data = {
|
|
||||||
agreementId,
|
|
||||||
signer: entity2,
|
|
||||||
role: 'user',
|
|
||||||
}
|
|
||||||
r = await jlincProcessAgreement(data)
|
|
||||||
if (r) {
|
|
||||||
if (printResults) {
|
|
||||||
console.log(`Result:`)
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
console.log(JSON.stringify(r, null, 2))
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
}
|
|
||||||
if (r.auditData && r.auditData.audit.agreementId === agreementId) {
|
|
||||||
console.log('PASS')
|
|
||||||
} else {
|
|
||||||
throw new Error('FAIL')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`\nAction: Produce (create and sign) event for data to be sent`)
|
|
||||||
data = {
|
|
||||||
from: entity1,
|
|
||||||
to: entity2,
|
|
||||||
agreementId,
|
|
||||||
payload: {
|
|
||||||
data: "testing",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r = await jlincProduceEvent(data)
|
|
||||||
if (r) {
|
|
||||||
if (printResults) {
|
|
||||||
console.log(`Result:`)
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
console.log(JSON.stringify(r, null, 2))
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
}
|
|
||||||
if (r.created && r.processed && r.created.agreementId === agreementId) {
|
|
||||||
console.log('PASS')
|
|
||||||
} else {
|
|
||||||
throw new Error('FAIL')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const eventId = r.created.eventId;
|
|
||||||
|
|
||||||
console.log(`\nAction: Process (sign) by the receiver after data is sent`)
|
|
||||||
data = {
|
|
||||||
to: entity2,
|
|
||||||
eventId,
|
|
||||||
}
|
|
||||||
r = await jlincProcessEvent(data)
|
|
||||||
if (r) {
|
|
||||||
console.log(`Result:`)
|
|
||||||
if (printResults) {
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
console.log(JSON.stringify(r, null, 2))
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
}
|
|
||||||
if (r.auditData && r.auditData.audit.eventId === eventId) {
|
|
||||||
console.log('PASS')
|
|
||||||
} else {
|
|
||||||
throw new Error('FAIL')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`\nAction: Produce (create and sign) event for data to be sent with successful auth`)
|
|
||||||
data = {
|
|
||||||
from: entity1,
|
|
||||||
to: entity2,
|
|
||||||
auth: {
|
|
||||||
subject: {
|
|
||||||
type: "user",
|
|
||||||
id: "tester",
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
name: "read",
|
|
||||||
},
|
|
||||||
resource: {
|
|
||||||
type: "data",
|
|
||||||
id: "1234",
|
|
||||||
properties: {
|
|
||||||
ownerID: "tester@test.com",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
payload: {
|
|
||||||
data: "testing",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r = await jlincProduceEvent(data)
|
|
||||||
if (r) {
|
|
||||||
if (printResults) {
|
|
||||||
console.log(`Result:`)
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
console.log(JSON.stringify(r, null, 2))
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
}
|
|
||||||
if (r.created && r.processed) {
|
|
||||||
console.log('PASS')
|
|
||||||
} else {
|
|
||||||
throw new Error('FAIL')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`\nAction: Produce (create and sign) event for data to be sent with failed auth`)
|
|
||||||
data = {
|
|
||||||
from: entity1,
|
|
||||||
to: entity2,
|
|
||||||
auth: {
|
|
||||||
subject: {
|
|
||||||
type: "user",
|
|
||||||
id: "tester",
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
name: "write",
|
|
||||||
},
|
|
||||||
resource: {
|
|
||||||
type: "data",
|
|
||||||
id: "1234",
|
|
||||||
properties: {
|
|
||||||
ownerID: "tester@test.com",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
payload: {
|
|
||||||
data: "testing",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
r = await jlincProduceEvent(data)
|
|
||||||
if (r) {
|
|
||||||
if (printResults) {
|
|
||||||
console.log(`Result:`)
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
console.log(JSON.stringify(r, null, 2))
|
|
||||||
console.log(`---------------------------------------------`)
|
|
||||||
}
|
|
||||||
if (r.decision != undefined && r.decision == false) {
|
|
||||||
console.log('PASS')
|
|
||||||
} else {
|
|
||||||
throw new Error('FAIL')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error("[*] ERROR:", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
+13
-1
@@ -1,6 +1,18 @@
|
|||||||
{
|
{
|
||||||
"extends": "./tsconfig.json",
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"rootDir": "./src",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": false,
|
||||||
|
"sourceMap": false,
|
||||||
|
"types": ["node"]
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.js", "src/**/*.d.ts"],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"./src/*.test.*"
|
"src/**/*.test.js",
|
||||||
|
"src/**/*.test.ts",
|
||||||
|
"src/integration",
|
||||||
|
"src/node_modules"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+15
-11
@@ -1,16 +1,20 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"allowJs": true,
|
"target": "ES2020",
|
||||||
"declaration": true,
|
"module": "commonjs",
|
||||||
"emitDeclarationOnly": true,
|
"lib": ["ES2020"],
|
||||||
"rootDir": "./src/",
|
"outDir": "./dist",
|
||||||
"outDir": "dist",
|
"rootDir": "./",
|
||||||
"target": "ESNext",
|
|
||||||
"module": "ESNext",
|
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"types": ["jest", "node"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["**/*.ts"],
|
||||||
"src"
|
"exclude": ["node_modules", "dist"]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user