Skip to content

Commit

Permalink
chore: vcl sdk full initialization including crypto services implemen…
Browse files Browse the repository at this point in the history
…tation
  • Loading branch information
michaelavoyan committed Jun 26, 2024
1 parent 44776d6 commit 8e34ba6
Show file tree
Hide file tree
Showing 19 changed files with 524 additions and 88 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/nodejs-sdk.workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
node-version: ${{ env.NODE_VERSION }}
# Set Github Packages Token
- name: Set Github Packages Token
run: echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" > ./apps/${{ inputs.app-path-name }}/.npmrc
# Install dependencies
- name: Install dependencies
run: yarn --frozen-lockfile --pure-lockfile
Expand Down
1 change: 0 additions & 1 deletion .npmrc

This file was deleted.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"author": "Andres Olave",
"license": "Apache 2.0",
"scripts": {
"lint": "eslint . --ext .js,.ts,.tsx",
"lint:fix": "eslint --fix --ext .js,.ts,.tsx .",
"lint": "eslint . --ext .js,.ts,.tsx,.json",
"lint:fix": "eslint --fix --ext .js,.ts,.tsx,.json .",
"test": "jest"
},
"engines": {
Expand Down
16 changes: 8 additions & 8 deletions packages/sample-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
"version": "0.0.1",
"description": "VNF Wallet Sample Nodejs Server",
"scripts": {
"lint": "eslint . --ext .js,.ts,.tsx",
"lint:fix": "eslint --fix --ext .js,.ts,.tsx .",
"lint": "eslint . --ext .js,.ts,.tsx,.json",
"lint:fix": "eslint --fix --ext .js,.ts,.tsx,.json .",
"test": "jest",
"dev": "NODE_ENV=dev ts-node-dev --log-error --files ./src/server.ts",
"build": "tsc -p tsconfig.json",
"start": "NODE_ENV=production node dist/server.js"
"start": "NODE_ENV=dev ts-node --log-error --files ./src/server.ts",
"start:dev": "NODE_ENV=dev ts-node-dev --log-error --files ./src/server.ts"
},
"author": "Andres Olave",
"license": "Apache-2.0",
"engines": {
"node": ">= 18.0.0"
"node": ">= 20.0.0"
},
"dependencies": {
"@fastify/autoload": "~5.7.1",
"axios": "^1.4.0",
"env-var": "~7.3.0",
"fastify": "~4.15.0",
"@velocitycareerlabs/vnf-nodejs-wallet-sdk": "^0.9.10"
"fastify": "~4.28.0",
"fastify-plugin": "4.5.1"
},
"devDependencies": {
"@jest/globals": "~29.5.0",
Expand Down
37 changes: 37 additions & 0 deletions packages/sample-server/src/crypto-services/JwtSignServiceImpl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import {
Nullish,
VCLJwt,
VCLJwtSignService,
VCLDidJwk,
VCLJwtDescriptor,
VCLToken
} from "@velocitycareerlabs/vnf-nodejs-wallet-sdk/src";
import { generateSignedJwtFetcher } from "../fetchers";

export class JwtSignServiceImpl implements VCLJwtSignService {
async sign(
jwtDescriptor: VCLJwtDescriptor,
didJwk: VCLDidJwk,
nonce: Nullish<string>,
// eslint-disable-next-line unused-imports/no-unused-vars,no-unused-vars
remoteCryptoServicesToken: Nullish<VCLToken>
): Promise<VCLJwt> {
try {
const jwtJson = await generateSignedJwtFetcher(jwtDescriptor, didJwk, nonce);
return new Promise((resolve) => {
resolve(VCLJwt.fromEncodedJwt(jwtJson['compactJwt'] as string));
});
} catch (e) {
return new Promise((resolve, reject) => {
reject(e);
});
}
}
}
27 changes: 27 additions & 0 deletions packages/sample-server/src/crypto-services/JwtVerifyServiceImpl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import { verifyJwtFetcher } from "../fetchers";
import { VCLPublicJwk, Nullish, VCLJwtVerifyService, VCLJwt } from "@velocitycareerlabs/vnf-nodejs-wallet-sdk/src";

export class JwtVerifyServiceImpl implements VCLJwtVerifyService {
async verify(
jwt: VCLJwt,
publicJwk: Nullish<VCLPublicJwk>,
): Promise<boolean> {
try {
const verificationJson = await verifyJwtFetcher(jwt, publicJwk);
return new Promise((resolve) => {
resolve(verificationJson['verified'] as boolean || false);
});
} catch (e) {
return new Promise((resolve, reject) => {
reject(e);
});
}
}
}
27 changes: 27 additions & 0 deletions packages/sample-server/src/crypto-services/KeyServiceImpl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import { VCLDidJwk, VCLDidJwkDescriptor, VCLKeyService } from "@velocitycareerlabs/vnf-nodejs-wallet-sdk/src";
import { generateDidJwkFetcher } from "../fetchers";

export class KeyServiceImpl implements VCLKeyService {

async generateDidJwk(didJwkDescriptor: VCLDidJwkDescriptor): Promise<VCLDidJwk> {
try {
const didJwkJson = await generateDidJwkFetcher(
didJwkDescriptor,
);
return new Promise((resolve) => {
resolve(VCLDidJwk.fromJSON(didJwkJson));
});
} catch (e) {
return new Promise((resolve, reject) => {
reject(e);
});
}
}
}
16 changes: 16 additions & 0 deletions packages/sample-server/src/crypto-services/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import { KeyServiceImpl } from './KeyServiceImpl';
import { JwtSignServiceImpl } from './JwtSignServiceImpl';
import { JwtVerifyServiceImpl } from './JwtVerifyServiceImpl';

export {
KeyServiceImpl,
JwtSignServiceImpl,
JwtVerifyServiceImpl
}
34 changes: 34 additions & 0 deletions packages/sample-server/src/fetchers/fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';

interface FetcherConfig<T> extends AxiosRequestConfig {
data?: T;
}

async function fetcher<T, R>(config: FetcherConfig<T>): Promise<R> {
const axiosConfig: AxiosRequestConfig = {
...config,
url: `${config.url}`,
};

try {
const response: AxiosResponse<R> = await axios(axiosConfig);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('Axios error:', error.message);
throw error;
} else {
console.error('Unexpected error:', error);
throw new Error('An unexpected error occurred');
}
}
}

export default fetcher;
23 changes: 23 additions & 0 deletions packages/sample-server/src/fetchers/generate-did-jwk-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import { getCreateDidKeyServiceUrl } from "./urls";
import { CurrentEnvironment } from "../global";
import fetcher from "./fetcher";
import { Dictionary, VCLDidJwkDescriptor } from "@velocitycareerlabs/vnf-nodejs-wallet-sdk/src";

export async function generateDidJwkFetcher(didJwkDescriptor: VCLDidJwkDescriptor): Promise<Dictionary<any>> {
const config = {
url: getCreateDidKeyServiceUrl(CurrentEnvironment),
method: 'POST',
data: {
crv: `${didJwkDescriptor.signatureAlgorithm}`,
didMethod: 'did:jwk',
}
};
return fetcher(config);
}
77 changes: 77 additions & 0 deletions packages/sample-server/src/fetchers/generate-signed-jwt-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import { getJwtSignServiceUrl } from "./urls";
import { CurrentEnvironment } from "../global";
import fetcher from "./fetcher";
import {
VCLJwt,
VCLDidJwk,
VCLJwtDescriptor,
Dictionary,
Nullish
} from "@velocitycareerlabs/vnf-nodejs-wallet-sdk/src";

export async function generateSignedJwtFetcher(
jwtDescriptor: VCLJwtDescriptor,
didJwk: VCLDidJwk,
nonce: Nullish<string>,
): Promise<Dictionary<any>> {
const config = {
url: getJwtSignServiceUrl(CurrentEnvironment),
method: 'POST',
data: generateJwtPayloadToSign(
jwtDescriptor,
nonce,
didJwk
),
};
return await fetcher(config);
}

function generateJwtPayloadToSign(
jwtDescriptor: VCLJwtDescriptor,
nonce: Nullish<string>,
didJwk: VCLDidJwk
): Dictionary<any> {
const retVal: Dictionary<any> = {};
const header: Dictionary<any> = {};
const options: Dictionary<any> = {};
const payload: Dictionary<any> = jwtDescriptor.payload ? { ...jwtDescriptor.payload } : {};

header[CodingKeys.KeyJwk] = didJwk.publicJwk.valueJson;
header[CodingKeys.KeyKid] = didJwk.kid;

options[CodingKeys.KeyKeyId] = didJwk.keyId;

payload[CodingKeys.KeyNonce] = nonce;
payload[CodingKeys.KeyAud] = jwtDescriptor.aud;
payload[CodingKeys.KeyJti] = jwtDescriptor.jti;
payload[CodingKeys.KeyIss] = jwtDescriptor.iss;

retVal[CodingKeys.KeyHeader] = header;
retVal[CodingKeys.KeyOptions] = options;
retVal[CodingKeys.KeyPayload] = payload;

return retVal;
}

const CodingKeys = {
KeyKeyId: "keyId",
KeyKid: "kid",
KeyJwk: "jwk",
KeyIss: "iss",
KeyAud: "aud",
KeyJti: "jti",
KeyNonce: "nonce",

KeyHeader: "header",
KeyOptions: "options",
KeyPayload: "payload",

KeyCompactJwt: "compactJwt"
};
16 changes: 16 additions & 0 deletions packages/sample-server/src/fetchers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Created by Michael Avoyan on 26/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import { verifyJwtFetcher } from './verify-jwt-fetcher';
import { generateSignedJwtFetcher } from './generate-signed-jwt-fetcher';
import { generateDidJwkFetcher } from './generate-did-jwk-fetcher';

export {
verifyJwtFetcher,
generateSignedJwtFetcher,
generateDidJwkFetcher
}
35 changes: 35 additions & 0 deletions packages/sample-server/src/fetchers/urls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/
import { VCLEnvironment } from "@velocitycareerlabs/vnf-nodejs-wallet-sdk/src";


const BaseUrl = "mockvendor.velocitycareerlabs.io";

function getServiceBaseUrl(environment: VCLEnvironment): string {
switch (environment) {
case VCLEnvironment.Dev:
return `https://${VCLEnvironment.Dev}.${BaseUrl}`;
case VCLEnvironment.Qa:
return `https://${VCLEnvironment.Qa}.${BaseUrl}`;
case VCLEnvironment.Staging:
return `https://${VCLEnvironment.Staging}.${BaseUrl}`;
default:
return `https://${BaseUrl}`;
}
}

export function getJwtSignServiceUrl(environment: VCLEnvironment): string {
return `${getServiceBaseUrl(environment)}/api/jwt/sign`;
}

export function getJwtVerifyServiceUrl(environment: VCLEnvironment): string {
return `${getServiceBaseUrl(environment)}/api/jwt/verify`;
}

export function getCreateDidKeyServiceUrl(environment: VCLEnvironment): string {
return `${getServiceBaseUrl(environment)}/api/create_did_key`;
}
28 changes: 28 additions & 0 deletions packages/sample-server/src/fetchers/verify-jwt-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Created by Michael Avoyan on 24/06/2024.
*
* Copyright 2022 Velocity Career Labs inc.
* SPDX-License-Identifier: Apache-2.0
*/

import { getJwtVerifyServiceUrl } from "./urls";
import { CurrentEnvironment } from "../global";
import fetcher from "./fetcher";
import { VCLPublicJwk, VCLJwt, Nullish, Dictionary } from "@velocitycareerlabs/vnf-nodejs-wallet-sdk/src";

export async function verifyJwtFetcher(jwt: VCLJwt, publicJwk: Nullish<VCLPublicJwk>): Promise<Dictionary<any>> {
const config = {
url: getJwtVerifyServiceUrl(CurrentEnvironment),
method: 'POST',
data: generatePayloadToVerify(jwt, publicJwk),
};
return fetcher(config);
}

function generatePayloadToVerify(jwt: VCLJwt, publicJwk: Nullish<VCLPublicJwk>): Record<string, any> {
const retVal: Record<string, any> = {};
retVal['jwt'] = jwt.encodedJwt;
retVal['publicKey'] = publicJwk?.valueJson || {};
return retVal;
}

Loading

0 comments on commit 8e34ba6

Please sign in to comment.