initial release build
This commit is contained in:
288
README.md
288
README.md
@@ -0,0 +1,288 @@
|
||||
# JLINC NodeJS SDK
|
||||
|
||||
The JLINC NodeJS SDK serves as a centralized vehicle for leveraging all aspects of the core JLINC protocol. This library will enable you to build client/server applications that leverage built-in secure identity management, agreement signing, and data exchange provided via the protocol.
|
||||
|
||||
Details of the JLINC protocol, schema, and context can be found at: https://protocol.jlinc.io/.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @jlinc/sdk
|
||||
```
|
||||
|
||||
## Sample usage
|
||||
The below code sample is a demonstration of the JLINC NodeJS SDK in action. As data moves through the system, it is cryptographically signed with a unique key for each element in the system, and zero-knowledge audit records are delivered to the JLINC Archive Server.
|
||||
|
||||
```js
|
||||
const {
|
||||
jlincInit,
|
||||
jlincProduceEvent,
|
||||
jlincProcessEvent,
|
||||
jlincProduceAgreement,
|
||||
jlincProcessAgreement,
|
||||
} = require("@jlinc/sdk");
|
||||
|
||||
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 in this agreement and data exchange
|
||||
const entity1 = `EntityOne`;
|
||||
const entity2 = `EntityTwo`;
|
||||
|
||||
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()
|
||||
```
|
||||
|
||||
|
||||
## API Reference
|
||||
|
||||
### `jlincInit(data: JLINCConfig)`
|
||||
Call `jlincInit` before using any other method. The configuration object supports the following properties:
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `dataStoreApiUrl` | `string` | `http://localhost:9090` | Base URL for the data store API |
|
||||
| `dataStoreApiKey` | `string` | | Bearer token for authenticating API requests |
|
||||
| `archiveApiUrl` | `string` | `http://localhost:9090` | URL for the archive service |
|
||||
| `archiveApiKey` | `string` | | API key for the archive service |
|
||||
| `systemPrefix` | `string` | `my-system` | *(Optional)* Prefix applied to all entity short names |
|
||||
| `domain` | `string` | Server Specified | *(Optional)* Default domain for entities. If not specified, it is auto-resolved on first call |
|
||||
| `defaultAgreementId` | `string` | `00000000-0000-0000-0000-000000000000` | *(Optional)* Default agreement ID for events |
|
||||
| `debug` | `boolean` | `false` | *(Optional)* Enables verbose console logging for requests/responses |
|
||||
|
||||
### `jlincProduceAgreement(data: JLINCProduceAgreementData)`
|
||||
Creates and publishes a new agreement.
|
||||
|
||||
**Parameters:**
|
||||
| Key | Type | Description |
|
||||
|-----|------|-------------|
|
||||
| `requiredSigners` | `Array<string>` | List of entities required to sign |
|
||||
| `signer` | `string` | The entity producing/signing this request |
|
||||
| `uri` | `string` | Resource URI the agreement applies to |
|
||||
| `purposes` | `Array<string>` | Allowed purposes under the agreement |
|
||||
| `caveats` | `Array<string>` | Prohibitions under the agreement |
|
||||
| `validRoles` | `Array<string>` | Allowed roles for the agreement |
|
||||
| `role` | `string` | The role being signing the agreement |
|
||||
| `auth` | `object` | *(Optional)* AuthZEN authentication data |
|
||||
|
||||
### `jlincProcessAgreement(data: JLINCProcessAgreementData)`
|
||||
Signs an existing agreement.
|
||||
|
||||
**Parameters:**
|
||||
| Key | Type | Description |
|
||||
|-----|------|-------------|
|
||||
| `agreementId` | `string` | The ID of the agreement to process |
|
||||
| `signer` | `string` | The entity signing the agreement |
|
||||
| `role` | `string` | The role being signed on behalf of |
|
||||
| `auth` | `object` | *(Optional)* AuthZEN authentication data |
|
||||
|
||||
### `jlincProduceEvent(data: JLINCProduceEventData)`
|
||||
Creates and publishes a new event.
|
||||
|
||||
**Parameters:**
|
||||
| Key | Type | Description |
|
||||
|-----|------|-------------|
|
||||
| `from` | `string` | The entity sending and signing the data |
|
||||
| `to` | `string` | The entity to receive the data |
|
||||
| `agreementId` | `string` | *(Optional)* Agreement ID. Falls back to `defaultAgreementId` if omitted |
|
||||
| `payload` | `any` | The data payload to send |
|
||||
| `auth` | `object` | *(Optional)* AuthZEN authentication data forwarded to the API |
|
||||
|
||||
### `jlincProcessEvent(data: JLINCProcessEventData)`
|
||||
Signs an existing agreement.
|
||||
|
||||
**Parameters:**
|
||||
| Key | Type | Description |
|
||||
|-----|------|-------------|
|
||||
| `to` | `string` | The entity receiving and signing the data |
|
||||
| `eventId` | `string` | The ID of the event to process |
|
||||
| `auth` | `object` | *(Optional)* AuthZEN authentication data |
|
||||
|
||||
Reference in New Issue
Block a user