Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge with client-ts v1.1.15 #12

Merged
merged 1 commit into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions client-rn/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@

2022-05-27 (v1.1.15)
-------------------

- Add more top level exports; Database, Datastore, Profile, Schema (#205)
- Support a fallback context to search when opening a public profile (#203 #194)
- Support auto-login from URL parameters to support URL redirection from the Vault (#199)
- Return empty array if no results from database when calling `getMany()` (#193)
- Add mocha types to resulve unit test errors
- Fix incorrect typing of `DatabaseOpenConfig` encryptionKey

2022-04-12 (v1.1.14)
-------------------

- Improve typing

2022-03-10 (v1.1.13)
-------------------

Expand Down
5 changes: 4 additions & 1 deletion client-rn/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@verida/client-rn",
"version": "1.1.13",
"version": "1.1.15",
"main": "dist/src/index.js",
"license": "ISC",
"directories": {
Expand Down Expand Up @@ -78,7 +78,10 @@
"@types/base-64": "^1.0.0",
"@types/lodash": "^4.14.179",
"@types/node": "^16.7.12",
"@types/crypto-pouch": "^4.0.1",
"@types/mocha": "^9.1.1",
"@types/pouchdb": "^6.4.0",
"@types/uuid": "^8.3.4",
"dependency-cruiser": "^11.3.0",
"mocha": "^8.2.1",
"ts-mocha": "^8.0.0",
Expand Down
14 changes: 11 additions & 3 deletions client-rn/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,18 @@ class Client {
public async openPublicProfile(
did: string,
contextName: string,
profileName: string = "basicProfile"
profileName: string = "basicProfile",
fallbackContext: string | null = "Verida: Vault"
): Promise<Profile | undefined> {
const context = await this.openExternalContext(contextName, did);
let context: Context | undefined;
try {
context = await this.openExternalContext(contextName, did);
} catch (error) {
if (fallbackContext) {
return await this.openPublicProfile(did, fallbackContext, profileName, null);
}
}

if (!context) {
throw new Error(
`Account does not have a public profile for ${contextName}`
Expand Down Expand Up @@ -281,7 +290,6 @@ class Client {
public async getSchema(schemaUri: string): Promise<Schema> {
return Schema.getSchema(schemaUri);
}

}

export default Client;
6 changes: 3 additions & 3 deletions client-rn/src/context/datastore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class Datastore {
*/
public async save(data: any, options: any = {}): Promise<object | boolean> {
await this.init();

data.schema = this.schemaPath;

let valid = await this.schema.validate(data);
Expand Down Expand Up @@ -219,10 +219,10 @@ class Datastore {
this.db = await this.context.openExternalDatabase(
dbName,
this.config.did!,
this.config
this.config as any
);
} else {
this.db = await this.context.openDatabase(dbName, this.config);
this.db = await this.context.openDatabase(dbName, this.config as any);
}
let indexes = schemaJson.database.indexes;

Expand Down
3 changes: 2 additions & 1 deletion client-rn/src/context/engines/verida/database/base-db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ class BaseDb extends EventEmitter implements Database {
return raw ? docs : docs.docs;
}

return;
// CouchDb returned something falsey
return [];
}

public async delete(doc: any, options: any = {}) {
Expand Down
6 changes: 5 additions & 1 deletion client-rn/src/context/engines/verida/messaging/inbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class VeridaInbox extends EventEmitter {

// TODO: Verify the DID-JWT with a custom VID resolver

let inboxEntry = {
let inboxEntry: any = {
_id: inboxItem._id, // Use the same _id to avoid duplicates
message: item.data.message,
type: item.data.type,
Expand All @@ -87,6 +87,10 @@ class VeridaInbox extends EventEmitter {
read: false,
};

if (inboxItem.openUrl) {
inboxEntry.openUrl = inboxItem.openUrl
}

// Save a new inbox entry into the user's private inbox
try {
await this.privateInbox.save(inboxEntry);
Expand Down
4 changes: 4 additions & 0 deletions client-rn/src/context/engines/verida/messaging/outbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ class VeridaOutbox {
sent: false,
};

if (config.openUrl) {
outboxEntry.openUrl = config.openUrl
}

const outbox = this.outboxDatastore;
const response: any = await outbox.save(outboxEntry);

Expand Down
3 changes: 2 additions & 1 deletion client-rn/src/context/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export interface DatabaseOpenConfig {
*
* This encryption key will not apply if the database is marked as `public`.
*/
encryptionKey?: string;
encryptionKey?: Buffer;

/**
* Create an application context if it doesn't already exist for the connected account.
Expand Down Expand Up @@ -116,4 +116,5 @@ export interface MessageSendConfig {
did: string,
expiry?: Number;
recipientContextName?: string;
openUrl?: string
}
8 changes: 8 additions & 0 deletions client-rn/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import Client from './client'
import Network from './network'
import Context from './context/context'
import Messaging from './context/messaging'
import Datastore from './context/datastore'
import Database from './context/database'
import { Profile } from './context/profiles/profile'
import Schema from './context/schema'
import * as ContextInterfaces from './context/interfaces'
import { EnvironmentType } from "@verida/account"
import * as Utils from './utils'
Expand All @@ -12,6 +16,10 @@ export {
Context,
Network,
Messaging,
Database,
Datastore,
Profile,
Schema,
ContextInterfaces,
EnvironmentType,
Utils
Expand Down
49 changes: 22 additions & 27 deletions client-rn/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import EncryptionUtils from '@verida/encryption-utils';
import url from 'url';
import { Context } from '.';
import { PermissionOptionsEnum } from './context/interfaces';
import { FetchUriParams } from './interfaces';
const bs58 = require('bs58')
const bs58 = require('bs58');

/**
* Build a URI that represents a specific record in a database
*
* @param did
* @param contextName
* @param databaseName
* @param itemId
* @param params
* @returns
*
* @param did
* @param contextName
* @param databaseName
* @param itemId
* @param params
* @returns
*/
export function buildVeridaUri(
did: string,
Expand All @@ -22,8 +21,8 @@ export function buildVeridaUri(
itemId?: string,
params?: { key?: string }
): string {
const bytes = Buffer.from(contextName)
const encodedContextName = bs58.encode(bytes)
const bytes = Buffer.from(contextName);
const encodedContextName = bs58.encode(bytes);
let uri = `verida://${did}/${encodedContextName}`;

if (databaseName) {
Expand All @@ -44,9 +43,9 @@ export function buildVeridaUri(

/**
* Explode a Verida URI into it's individual pieces
*
* @param uri
* @returns
*
* @param uri
* @returns
*/
export function explodeVeridaUri(uri: string): FetchUriParams {
const regex = /^verida:\/\/(.*)\/(.*)\/(.*)\/(.*)\?(.*)$/i;
Expand All @@ -58,8 +57,8 @@ export function explodeVeridaUri(uri: string): FetchUriParams {

const did = matches[1] as string;
const encodedContextName = matches[2];
const bytes = bs58.decode(encodedContextName)
const contextName = Buffer.from(bytes).toString()
const bytes = bs58.decode(encodedContextName);
const contextName = Buffer.from(bytes).toString();
const dbName = matches[3];
const id = matches[4];
const query = url.parse(uri, true).query;
Expand All @@ -75,15 +74,12 @@ export function explodeVeridaUri(uri: string): FetchUriParams {

/**
* Fetch the data accessible from a Verida URI
*
*
* @param uri Verida URI of the record to access
* @param context An existing context used to open the external database
* @returns
* @returns
*/
export async function fetchVeridaUri(
uri: string,
context: Context
): Promise<string> {
export async function fetchVeridaUri(uri: string, context: any): Promise<string> {
const url = explodeVeridaUri(uri);

const db = await context.openExternalDatabase(url.dbName, url.did, {
Expand All @@ -96,16 +92,15 @@ export async function fetchVeridaUri(
readOnly: true,
});


try {
const item: any = await db.get(url.id, {})
const item: any = await db.get(url.id, {});
const key = Buffer.from(url.query.key as string, 'hex');

// Retur encrypted data if provided with an encryption key
// Return encrypted data if provided with an encryption key
if (key) {
return EncryptionUtils.symDecrypt(item.content, key);
}

// Otherwise return the actual data
return item;
} catch (err: any) {
Expand All @@ -115,4 +110,4 @@ export async function fetchVeridaUri(

throw err;
}
}
}
53 changes: 53 additions & 0 deletions client-rn/test/profile.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,59 @@ describe('Profile tests', () => {
const name = await profile2.get("name")
assert.equal(name, DATA.name, "Can get external public profile data")
})

describe("Using Client to open public profiles", function () {
const wrongContextName = "Context: Wrong Name";
const wrongFallbackContextName = "Context: Wrong Name 2";

it('can use fallbackContext="Verida: Vault" to open public profile', async () => {
const profile = await client1.openPublicProfile(
did1,
wrongContextName
);
const name = await profile.get("name");

assert.equal(name, DATA.name, "Can get a profile value");
});

it("can disable fallbackContext on open public profile", async () => {
const profile = await client1.openPublicProfile(
did1,
CONFIG.CONTEXT_NAME,
"basicProfile",
null
);
const name = await profile.get("name");

assert.equal(name, DATA.name, "Can get a profile value");
});

it("can not open a public profile using the wrong context and without fallbackContext", async () => {
await assert.rejects(async () => {
await client1.openPublicProfile(
did1,
wrongContextName,
"basicProfile",
null
);
}, {
message: `Account does not have a public profile for ${wrongContextName}`
})
});

it("can not open a public profile using both the wrong context and wrong fallbackContext", async () => {
await assert.rejects(async () => {
await client1.openPublicProfile(
did1,
wrongContextName,
"basicProfile",
wrongFallbackContextName
);
}, {
message: `Account does not have a public profile for ${wrongFallbackContextName}`
})
});
});
})

// @todo: add tests for private profiles
Expand Down