Skip to content

Commit

Permalink
Merge pull request #12 from verida/fetch-upstream-client-ts-v1.1.15
Browse files Browse the repository at this point in the history
Merge with client-ts v1.1.15
  • Loading branch information
andy-verida authored Jul 4, 2022
2 parents 54a369f + 8b407c1 commit dbf3f56
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 37 deletions.
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

0 comments on commit dbf3f56

Please sign in to comment.