upgrade to 1.1.0
This commit is contained in:
1 parent
02c95d89bb
commit
f5893a107d
46 files changed
+3762
-2889
No files matched your search
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
.env
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
node_modules
|
||||
.env
|
||||
**/.env*
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
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 = {
|
||||
debug?: boolean | undefined;
|
||||
systemPrefix?: string | undefined;
|
||||
defaultAgreementId?: string | undefined;
|
||||
domain?: string | null | undefined;
|
||||
dataStoreApiUrl?: string | null | undefined;
|
||||
dataStoreApiKey?: string | null | undefined;
|
||||
archiveApiUrl?: string | null | undefined;
|
||||
archiveApiKey?: string | null | undefined;
|
||||
};
|
||||
export type JLINCProduceEventData = {
|
||||
to?: string | undefined;
|
||||
from?: string | undefined;
|
||||
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>;
|
||||
export let init: typeof import("./config.js").init;
|
||||
export let auth: typeof import("./auth.js").auth;
|
||||
export let getDomains: typeof import("./entity.js").getDomains;
|
||||
export let getEntity: typeof import("./entity.js").getEntity;
|
||||
export let createEntity: typeof import("./entity.js").createEntity;
|
||||
export let produceAgreement: typeof import("./agreement.js").produceAgreement;
|
||||
export let processAgreement: typeof import("./agreement.js").processAgreement;
|
||||
export let getAgreement: typeof import("./agreement.js").getAgreement;
|
||||
export let produceEvent: typeof import("./event.js").produceEvent;
|
||||
export let getEvent: typeof import("./event.js").getEvent;
|
||||
export let processEvent: typeof import("./event.js").processEvent;
|
||||
export let getAudits: typeof import("./audit.js").getAudits;
|
||||
export let verifyAudit: typeof import("./audit.js").verifyAudit;
|
||||
Vendored
+15
-262
@@ -1,263 +1,16 @@
|
||||
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;
|
||||
}
|
||||
|
||||
"use strict";
|
||||
module.exports = {
|
||||
jlincInit,
|
||||
jlincProduceEvent,
|
||||
jlincProcessEvent,
|
||||
jlincProduceAgreement,
|
||||
jlincProcessAgreement,
|
||||
}
|
||||
init: require('./config.js').init,
|
||||
auth: require('./auth.js').auth,
|
||||
getDomains: require('./entity.js').getDomains,
|
||||
getEntity: require('./entity.js').getEntity,
|
||||
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
+1441
-1609
File diff suppressed because it is too large.
Load diff
+31
-21
@@ -1,17 +1,26 @@
|
||||
{
|
||||
"name": "@jlinc/sdk",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"description": "JLINC SDK for utilizing the JLINC API.",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "rm -rf dist && tsc --project tsconfig.build.json && cp src/index.js dist/"
|
||||
"main": "./dist/jlinc.cjs",
|
||||
"types": "./dist/jlinc.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/jlinc.d.ts",
|
||||
"default": "./dist/jlinc.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/jlinc.cjs.d.ts",
|
||||
"default": "./dist/jlinc.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"homepage": "https://www.jlinc.com/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"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": [
|
||||
"jlinc",
|
||||
@@ -19,17 +28,18 @@
|
||||
"governance",
|
||||
"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": [
|
||||
"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 = {
|
||||
jlincInit,
|
||||
jlincProduceEvent,
|
||||
jlincProcessEvent,
|
||||
jlincProduceAgreement,
|
||||
jlincProcessAgreement,
|
||||
}
|
||||
init: require('./config.js').init,
|
||||
auth: require('./auth.js').auth,
|
||||
getDomains: require('./entity.js').getDomains,
|
||||
getEntity: require('./entity.js').getEntity,
|
||||
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,
|
||||
};
|
||||
+307
-164
@@ -1,183 +1,326 @@
|
||||
require('dotenv').config({ quiet: true })
|
||||
const {
|
||||
jlincInit,
|
||||
jlincProduceEvent,
|
||||
jlincProcessEvent,
|
||||
jlincProduceAgreement,
|
||||
jlincProcessAgreement,
|
||||
} = require("./index.js");
|
||||
const axios = require('axios');
|
||||
const jlinc = require('./index');
|
||||
|
||||
const printResults = false;
|
||||
jest.mock('axios');
|
||||
|
||||
function printResult(data) {
|
||||
if (printResults) {
|
||||
console.log(`Result`);
|
||||
console.log("---------------------------------------------");
|
||||
console.log(JSON.stringify(data, null, 2));
|
||||
console.log("---------------------------------------------");
|
||||
}
|
||||
}
|
||||
const mockedAxios = axios;
|
||||
|
||||
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;
|
||||
}
|
||||
const mockResponse = (data) => ({ data });
|
||||
const mockPost = jest.fn();
|
||||
|
||||
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);
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockedAxios.post = mockPost;
|
||||
mockPost.mockImplementation((url, data, config) => Promise.resolve(mockResponse({ ok: true, url, data, 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", () => {
|
||||
let data;
|
||||
let r;
|
||||
let agreementId;
|
||||
let eventId;
|
||||
describe('auth', () => {
|
||||
it('should POST to /api/v1/auth with correct payload and headers', async () => {
|
||||
const subject = { type: 'user', id: 'tester' };
|
||||
const action = { name: 'read' };
|
||||
const resource = { type: 'data', id: '1234', properties: { ownerID: 'tester@test.com' } };
|
||||
|
||||
// Define participants
|
||||
const p1 = generateRandomString(11);
|
||||
const p2 = generateRandomString(11);
|
||||
await jlinc.auth({ subject, action, resource });
|
||||
|
||||
it(`Produce (create and sign) agreement`, async () => {
|
||||
data = {
|
||||
uri: 'http://localhost:9090/agreements/05c93a30cc699cfaee9185f23a5f68ffb12305acce1ca4b9444758fc4d594828',
|
||||
validRoles: ['provider', 'user'],
|
||||
purposes: ['testing'],
|
||||
caveats: ['production'],
|
||||
requiredSigners: [p1],
|
||||
signer: p1,
|
||||
role: 'provider',
|
||||
}
|
||||
r = await jlincProduceAgreement(data)
|
||||
expect(r).toBeDefined();
|
||||
printResult(r);
|
||||
expect(r.created && r.processed).toBeDefined();
|
||||
agreementId = r.created.agreementId
|
||||
})
|
||||
expect(mockPost).toHaveBeenCalledWith(
|
||||
'http://localhost:9090/api/v1/auth',
|
||||
{ subject, action, resource },
|
||||
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it(`Process (cross sign) agreement`, async () => {
|
||||
data = {
|
||||
agreementId,
|
||||
signer: p2,
|
||||
role: 'user',
|
||||
}
|
||||
r = await jlincProcessAgreement(data)
|
||||
expect(r).toBeDefined();
|
||||
printResult(r);
|
||||
expect(r.auditData).toBeDefined();
|
||||
expect(r.auditData.audit.agreementId === agreementId).toBe(true);
|
||||
})
|
||||
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' } };
|
||||
|
||||
it(`Produce (create and sign) event for data to be sent`, async () => {
|
||||
data = {
|
||||
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;
|
||||
})
|
||||
await jlinc.getDomains({ fedidUrl: 'http://fedid.test', auth: authPayload });
|
||||
|
||||
it(`Process (sign) by the receiver after data is received`, async () => {
|
||||
data = {
|
||||
to: p2,
|
||||
eventId,
|
||||
}
|
||||
r = await jlincProcessEvent(data)
|
||||
expect(r).toBeDefined();
|
||||
printResult(r);
|
||||
expect(r.auditData).toBeDefined();
|
||||
expect(r.auditData.audit.eventId === eventId).toBe(true);
|
||||
})
|
||||
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(`Produce (create and sign) event for data to be sent with successful auth`, async () => {
|
||||
data = {
|
||||
from: p1,
|
||||
to: p2,
|
||||
auth: {
|
||||
subject: {
|
||||
type: "user",
|
||||
id: "tester",
|
||||
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',
|
||||
};
|
||||
|
||||
await jlinc.produceAgreement(params);
|
||||
|
||||
expect(mockPost).toHaveBeenCalledWith(
|
||||
'http://localhost:9090/api/v1/data/agreement/produce',
|
||||
{
|
||||
...params,
|
||||
archive: { url: 'http://localhost:9090', key: 'test-archive-key' },
|
||||
},
|
||||
action: {
|
||||
name: "read",
|
||||
{ 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',
|
||||
archive: { url: 'http://localhost:9090', key: 'test-archive-key' },
|
||||
},
|
||||
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);
|
||||
})
|
||||
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||
);
|
||||
});
|
||||
|
||||
it(`Produce (create and sign) event for data to be sent with failed auth`, async () => {
|
||||
data = {
|
||||
from: p1,
|
||||
to: p2,
|
||||
auth: {
|
||||
subject: {
|
||||
type: "user",
|
||||
id: "tester",
|
||||
it('should fall back to default agreementId when not provided', async () => {
|
||||
await jlinc.processAgreement({ shortName: 'user', role: 'user' });
|
||||
|
||||
expect(mockPost).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.objectContaining({ agreementId: 'default-agreement-id' }),
|
||||
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAgreement', () => {
|
||||
it('should POST to /api/v1/data/agreement/get with correct payload', async () => {
|
||||
await jlinc.getAgreement({ agreementId: 'agr-1', includeSignatures: true });
|
||||
|
||||
expect(mockPost).toHaveBeenCalledWith(
|
||||
'http://localhost:9090/api/v1/data/agreement/get',
|
||||
{ agreementId: 'agr-1', includeSignatures: true },
|
||||
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||
);
|
||||
});
|
||||
|
||||
it('should fall back to default agreementId when not provided', async () => {
|
||||
await jlinc.getAgreement({ includeSignatures: true });
|
||||
|
||||
expect(mockPost).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.objectContaining({ agreementId: 'default-agreement-id' }),
|
||||
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
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' },
|
||||
},
|
||||
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);
|
||||
})
|
||||
})
|
||||
{ headers: { Authorization: 'Bearer test-api-key' } }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error("[*] ERROR:", err);
|
||||
}
|
||||
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' } }
|
||||
);
|
||||
});
|
||||
|
||||
main()
|
||||
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()
|
||||
+16
-4
@@ -1,6 +1,18 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": [
|
||||
"./src/*.test.*"
|
||||
]
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"declarationMap": false,
|
||||
"sourceMap": false,
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.js", "src/**/*.d.ts"],
|
||||
"exclude": [
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.test.ts",
|
||||
"src/integration",
|
||||
"src/node_modules"
|
||||
]
|
||||
}
|
||||
+18
-14
@@ -1,16 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"rootDir": "./src/",
|
||||
"outDir": "dist",
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"strict": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
Reference in new issue
Block a user