Skip to content

Commit

Permalink
move web5-js test into this repo (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
finn-tbd authored Oct 16, 2023
1 parent 0ffbc33 commit 6cbe8da
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 22 deletions.
11 changes: 8 additions & 3 deletions .github/workflows/self-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ on: [push]
jobs:
self-test:
runs-on: ubuntu-latest
strategy:
matrix:
SDK:
- web5-js
# - web5-kt
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- name: clone test target
run: git clone -b web5-component-tests https://github.com/TBD54566975/web5-js.git web5-js
- name: self test
run: go run ./cmd/web5-spec-test web5-js/
run: go run ./cmd/web5-spec-test sdks/$SDK
env:
SDK: ${{ matrix.SDK }}
22 changes: 21 additions & 1 deletion cmd/web5-spec-test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"time"

"github.com/TBD54566975/web5-spec/openapi"
Expand All @@ -17,6 +18,12 @@ var (
nostart = flag.Bool("no-start", false, "when set, the server is not built and is expected to be already running")
nostop = flag.Bool("no-stop", false, "when set, the server is not asked to shut down")
server = flag.String("server", "http://localhost:8080", "url of the server to connect to")

dockerfiles = []string{
".web5-component/test.Dockerfile",
".web5-component/Dockerfile",
"web5-spec.Dockerfile",
}
)

func main() {
Expand All @@ -31,7 +38,20 @@ func main() {
slog.SetDefault(slog.New(logger))

if !*nostart {
cmd := run(dir, "docker", "build", "-t", "web5-component:latest", "-f", ".web5-component/test.Dockerfile", ".")
var dockerfile string
for _, d := range dockerfiles {
candidate := filepath.Join(dir, d)
if _, err := os.Stat(candidate); !os.IsNotExist(err) {
dockerfile = d
}
}

if dockerfile == "" {
slog.Error("no dockerfile found", "paths", dockerfiles)
os.Exit(1)
}

cmd := run(dir, "docker", "build", "-t", "web5-component:latest", "-f", dockerfile, ".")
if err := cmd.Run(); err != nil {
slog.Error("error building server", "error", err)
os.Exit(1)
Expand Down
18 changes: 0 additions & 18 deletions docker-compose.yml

This file was deleted.

49 changes: 49 additions & 0 deletions sdks/web5-js/credentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Request, Response } from 'express';
import { VcJwt, VerifiableCredential, SignOptions } from '@web5/credentials';
import { DidKeyMethod, PortableDid } from '@web5/dids';
import { Ed25519, Jose } from '@web5/crypto';
import { paths } from './openapi.js';

type Signer = (data: Uint8Array) => Promise<Uint8Array>;

let _ownDid: PortableDid;

async function getOwnDid(): Promise<PortableDid> {
if(_ownDid) {
return _ownDid;
}
_ownDid = await DidKeyMethod.create();
return _ownDid;
}

export async function issueCredential(req: Request, res: Response) {
const body: paths["/credentials/issue"]["post"]["requestBody"]["content"]["application/json"] = req.body;

const ownDid = await getOwnDid()

// build signing options
const [signingKeyPair] = ownDid.keySet.verificationMethodKeys!;
const privateKey = (await Jose.jwkToKey({ key: signingKeyPair.privateKeyJwk!})).keyMaterial;
const subjectIssuerDid = ownDid.did;
const signer = EdDsaSigner(privateKey);
const signOptions: SignOptions = {
issuerDid : ownDid.did,
subjectDid : ownDid.did,
kid : '#' + ownDid.did.split(':')[2],
signer : signer
};

const vcJwt: VcJwt = await VerifiableCredential.create(signOptions);
// const resp: paths["/credentials/issue"]["post"]["responses"]["200"]["content"]["application/json"] = {
// verifiableCredential: {
// },
// }
res.json(vcJwt);
}

function EdDsaSigner(privateKey: Uint8Array): Signer {
return async (data: Uint8Array): Promise<Uint8Array> => {
const signature = await Ed25519.sign({ data, key: privateKey});
return signature;
};
}
40 changes: 40 additions & 0 deletions sdks/web5-js/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import express from 'express';
import { issueCredential } from './credentials.js';
import type * as http from 'http';
import type { Request, Response } from 'express'
import { paths } from './openapi.js' // generated with npx openapi-typescript .web5-component/openapi.yaml -o .web5-component/openapi.d.ts
import bodyparser from 'body-parser';

const app: express.Application = express();
app.use(express.json());
app.use(bodyparser.json());

app.post("/credentials/issue", issueCredential);

const serverID: paths["/"]["get"]["responses"]["200"]["content"]["application/json"] = {
name: "web5-js",
language: "JavaScript",
url: "https://github.com/TBD54566975/web5-js",
}
app.get("/", (req, res) => {
res.json(serverID);
});

let server: http.Server;
app.get("/shutdown", (req: Request, res: Response) => {
res.send("ok");
console.log("shutting down server");
server.close((e) => {
if(e) {
console.error(e);
}
});
});

server = app.listen(8080, () => console.log("test server started"));
process.on('SIGTERM', () => {
console.log('SIGTERM signal received: closing HTTP server')
server.close(() => {
console.log('HTTP server closed')
})
})
138 changes: 138 additions & 0 deletions sdks/web5-js/openapi.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/**
* This file was auto-generated by openapi-typescript.
* Do not make direct changes to the file.
*/


export interface paths {
"/credentials/issue": {
post: operations["credential_issue"];
};
"/ready": {
get: operations["server_ready"];
};
"/shutdown": {
get: operations["server_shutdown"];
};
"/": {
get: operations["identify_self"];
};
}

export type webhooks = Record<string, never>;

export interface components {
schemas: {
CredentialIssuanceRequest: {
credential: components["schemas"]["CredentialIssuanceRequestCredential"];
options: components["schemas"]["CredentialIssuanceRequestOptions"];
};
CredentialIssuanceRequestCredential: {
"@context": string[];
id: string;
type: string[];
issuer: components["schemas"]["CredentialIssuer"];
issuanceDate: string;
expirationDate: string;
credentialSubject: components["schemas"]["CredentialSubject"];
};
CredentialIssuanceRequestOptions: {
created: string;
challenge: string;
domain: string;
credentialStatus: components["schemas"]["CredentialStatus"];
};
CredentialIssuer: {
id: string;
};
CredentialSubject: {
[key: string]: unknown;
};
CredentialStatus: {
type: string;
};
CredentialIssuanceResponse: {
verifiableCredential: components["schemas"]["VerifiableCredential"];
};
VerifiableCredential: {
"@context": string[];
id: string;
type: string[];
issuer: components["schemas"]["CredentialIssuer"];
issuanceDate: string;
expirationDate: string;
credentialSubject: components["schemas"]["CredentialSubject"];
proof: components["schemas"]["CredentialProof"];
};
CredentialProof: {
type: string;
created: string;
challenge: string;
domain: string;
nonce: string;
verificationMethod: string;
proofPurpose: string;
jws: string;
proofValue: string;
};
TestServerID: {
name: string;
language: string;
url: string;
};
};
responses: never;
parameters: never;
requestBodies: never;
headers: never;
pathItems: never;
}

export type $defs = Record<string, never>;

export type external = Record<string, never>;

export interface operations {

credential_issue: {
requestBody: {
content: {
"application/json": components["schemas"]["CredentialIssuanceRequest"];
};
};
responses: {
/** @description Successful operation */
200: {
content: {
"application/json": components["schemas"]["CredentialIssuanceResponse"];
};
};
};
};
server_ready: {
responses: {
/** @description server is ready */
200: {
content: never;
};
};
};
server_shutdown: {
responses: {
/** @description server will shut down */
204: {
content: never;
};
};
};
identify_self: {
responses: {
/** @description information about the test server */
200: {
content: {
"application/json": components["schemas"]["TestServerID"];
};
};
};
};
}
27 changes: 27 additions & 0 deletions sdks/web5-js/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"compilerOptions": {
// "strict": true,
"lib": [
"DOM",
"ES6"
],
"allowJs": true,
"target": "es6",
"module": "NodeNext",
"declaration": true,
"declarationMap": true,
"declarationDir": "dist/types",
"outDir": "dist",
// `NodeNext` will throw compilation errors if relative import paths are missing file extension
// reference: https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#ecmascript-module-support-in-node-js
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"resolveJsonModule": true
},
"include": [
"main.ts",
],
"exclude": [
"node_modules"
]
}
8 changes: 8 additions & 0 deletions sdks/web5-js/web5-spec.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM node:18-alpine
RUN apk add --no-cache git
RUN git clone https://github.com/TBD54566975/web5-js.git /web5-js && cd /web5-js && npm ci && npm run build
WORKDIR /web5-js
RUN npm install express express-openapi
ADD . /web5-js/.web5-component
RUN npx tsc -p .web5-component/tsconfig.json
CMD ["node", ".web5-component/dist/main.js"]

0 comments on commit 6cbe8da

Please sign in to comment.