Skip to content

Commit

Permalink
Merge pull request #8 from algorandfoundation/feat/connect-rtc
Browse files Browse the repository at this point in the history
Feat/connect rtc
  • Loading branch information
PhearZero authored Apr 24, 2024
2 parents a94ddc8 + ce75747 commit 0a37622
Show file tree
Hide file tree
Showing 132 changed files with 19,583 additions and 9,414 deletions.
60 changes: 60 additions & 0 deletions .decisions/3-Peer-to-Peer-Signaling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Overview

Communicating across platforms in a decentralized manner

## Decisions

- Limit dependency on WebSockets to signaling
- Allow bidirectional communication between peers
- Enforce locality of device?

## Implementation

A WebSocket Service should establish the SDP handshake and emit ICE candidates for WebRTC clients.

This implementation should replace Wallet Connect with the following sequence
```mermaid
sequenceDiagram
participant Website
participant Server
participant Wallet
Note over Website, Wallet: Link devices
Website->>Server: GET Challenge Message
Server->>Website: Send Challenge Message
Website-->>Website: Display QR Connect Nonce
Website->>Server: Subscribe to 'wss:link'
Wallet->>Website: Scan QR Code
Wallet->>Server: POST Nonce + Signature + Answer
Server-->>Server: Validate Signature
Server-->>Website: HTTPOnly Session
Server->>Wallet: Ok Response + HTTPOnly Session
Server->>Website: Emit to `wss:link` client
Note over Website, Wallet: Passkeys/FIDO2
Website-->>Website: Continue FIDO2 Flow
Wallet-->>Wallet: Continue FIDO2 Flow
Note over Website, Wallet: Signaling Peer Offer/Answer
Website-->>Server: Subscribe to 'wss:answer-${address}'
Wallet-->>Server: Subscribe to 'wss:offer-${address}'
Website-->>Website: Create Peer Offer & DataChannel
Website-->>Server: POST Offer
Server-->>Wallet: Emit Offer
Wallet-->>Wallet: Create Peer Answer with Offer & DataChannel
Wallet-->>Server: POST Answer
Server-->>Website: Emit Answer
Website-->>Website: Set Remote SDP
Website-->>Website: Discover ICE Candidates
Website->>Server: Emit candidates to `wss:offer-${address}`
Server->>Wallet: Emit candidates to `wss:offer-${address}`
Wallet-->>Wallet: Set Candidates
Wallet-->>Wallet: Discover ICE Candidates
Wallet->>Server: Emit candidates to `wss:answer-${address}`
Server->>Website: Emit to `wss:answer`
Website->>Website: Set Candidates
```

*Note: This process may be deprecated in the future in favor of `libp2p` which allows for an agnostic discovery layer and also supports the WebRTC transport
4 changes: 2 additions & 2 deletions .env.docker
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ REDIS_PASSWORD=

# FIDO2
RP_NAME=Algorand Foundation FIDO2 Server
HOSTNAME=fido-home.telluric.guru
ORIGIN=https://fido-home.telluric.guru
HOSTNAME=catfish-pro-wolf.ngrok-free.app
ORIGIN=https://catfish-pro-wolf.ngrok-free.app

ANDROID_SHA256HASH=47:CC:4E:EE:B9:50:59:A5:8B:E0:19:45:CA:0A:6D:59:16:F9:A9:C2:96:75:F8:F3:64:86:92:46:2B:7D:5D:5C
ANDROID_PACKAGENAME=foundation.algorand.demo
23 changes: 23 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: CI
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 18.x, 20.x ]
steps:
- name: Checkout
uses: actions/checkout@master
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies
run: npm install
- name: Run Build
run: npm run build
- name: Lint Codebase
run: npm run lint
- name: Unit Tests with Coverage
run: npm run test:cov
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
swagger-codegen-cli.jar
ngrok.yml

.data
.idea

Expand Down
53 changes: 1 addition & 52 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,3 @@
# Overview
# Overview[WIP]

This is a guide on how to get the project running and how to contribute


## Getting started

### Prerequisites
- Node.js 20
- Docker

#### Clone the project

```bash
git clone [email protected]:algorandfoundation/liquid-auth.git && cd liquid-auth
```

#### Install package dependencies

```bash
npm install
```

#### Start services

```bash
docker-compose up -d
```

WebAuthn requires a secure context (HTTPS) to work and this will not allow you to test the FIDO2 feature in your local machine.

### NGROK

Sign up for a free account at [ngrok](https://ngrok.com/) and install the ngrok package.
Configure a Static Domain for your ngrok account and update the [.env](services/liquid-auth-api-js/README.md) file with the following keys with the values from ngrok:

```bash
HOSTNAME=example-static-domain.ngrok-free.app
ORIGIN=https://example-static-domain.ngrok-free.app
```

#### Run the ngrok proxy

```bash
ngrok http --domain=example-static-domain.ngrok-free.app 3000
```

#### Run the Authentication Service
```bash
npm run dev
```

Navigate to the ngrok URL in your browser to test the FIDO2 feature.

11 changes: 9 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ RUN npm run build

FROM node:20-alpine

# App Files
COPY --from=BUILDER ./node_modules ./node_modules
COPY --from=BUILDER ./package.json ./package.json
COPY --from=BUILDER ./package-lock.json ./package-lock.json
# Client Files
COPY --from=BUILDER ./clients ./clients
# Service Files
COPY --from=BUILDER ./services/liquid-auth-api-js/assetlinks.json ./services/liquid-auth-api-js/assetlinks.json
COPY --from=BUILDER ./services/liquid-auth-api-js/dist ./services/liquid-auth-api-js/dist
COPY --from=BUILDER ./services/liquid-auth-api-js/views ./services/liquid-auth-api-js/views
COPY --from=BUILDER ./services/liquid-auth-api-js/public ./services/liquid-auth-api-js/public
COPY --from=BUILDER ./services/liquid-auth-api-js/bin ./services/liquid-auth-api-js/bin
COPY --from=BUILDER ./services/liquid-auth-api-js/.env.template ./services/liquid-auth-api-js/.env.template
COPY --from=BUILDER ./services/liquid-auth-api-js/package.json ./services/liquid-auth-api-js/package.json

RUN npm ci --production

# Expose the port on which the app will run
EXPOSE 3000

Expand Down
59 changes: 58 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,66 @@ This project holds the standard FIDO2 api endpoints and the Proof of Knowledge f
The api is a stateful session-based architecture with endpoint guards.
A user must prove ownership of a private key to associate PublicKeyCredentials

## Getting started

### Prerequisites
- Node.js 20
- Docker

#### Clone the project

```bash
git clone [email protected]:algorandfoundation/liquid-auth.git && cd liquid-auth
```

#### Install package dependencies

WebAuthn requires a secure context (HTTPS) to work and this will not allow you to test the FIDO2 feature in your local machine.

### NGROK

Sign up for a free account at [ngrok](https://ngrok.com/) and install the ngrok package.
Configure a Static Domain for your ngrok account and update the [.env](services/liquid-auth-api-js/README.md) file with the following keys with the values from ngrok:


#### Configure NGROK

Add a `ngrok.yml` configuration to the root directory.

##### Example Configuration
```yaml
version: 2
authtoken: <NGROK_AUTH_TOKEN>
tunnels:
website:
addr: liquid-demo:5173
proto: http
domain: <NGROK_STATIC_DOMAIN>

```
*Make sure to update the `authtoken` and `domain` in the `ngrok.yml` file with your ngrok details.*

#### Update the Service's .docker.env file

```bash
HOSTNAME=<NGROK_STATIC_DOMAIN>
ORIGIN=https://<NGROK_STATIC_DOMAIN>
```

### Start services

Run the following command to start the backend:

```bash
docker-compose up -d
```

Navigate to the ngrok URL in your browser to test the FIDO2 feature.


## Using the app

#### Install the [Android client]() to your device and navigate to https://nest-fido2.onrender.com/.
#### Install the [Android client](https://github.com/awesome-algorand/android-authentication-client) to your device.

![Step-1.png](.docs%2FStep-1.png)

Expand Down
12 changes: 12 additions & 0 deletions Vite.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM node:20-alpine

ADD . .

RUN npm install

RUN npm run build


EXPOSE 5173

CMD ["npm", "run", "dev:ui"]
12 changes: 12 additions & 0 deletions client-gen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@


CODEGEN=swagger-codegen-cli.jar
if [ -f $CODEGEN ]; then
echo "Codegen already exists"
else
echo "Downloading codegen"
wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.52/swagger-codegen-cli-3.0.52.jar -O swagger-codegen-cli.jar
fi

java -jar swagger-codegen-cli.jar generate -i http://localhost:3000/api-json -l typescript-fetch -o clients/liquid-auth-client-js/src/client
java -jar swagger-codegen-cli.jar generate -i http://localhost:3000/api-json -l kotlin-client -o clients/liquid-auth-client-kotlin
59 changes: 59 additions & 0 deletions clients/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Overview

Client JSON-RPC interfaces are generated from OpenAPI 3.0 specifications.
All clients should mirror the same interfaces and include the same parameters (as much as possible).

```typescript
interface SignalClient {
readonly url: string; // Origin of the service
type: "offer" | "answer" // Type of client
peerClient: RTCPeerConnection | PeerClient // Native WebRTC Wrapper/Interface
socket: Socket // The socket to the service

readonly authenticated: boolean; // State of authentication
readonly requestId?: string; // The current request being signaled

/**
* Generate a Request ID
*/
generateRequestId(): any;

/**
* Top level Friendly interface for signaling
* @param args
*/
peer(requestId: any, type: 'offer' | 'answer', config?: RTCConfiguration): Promise<void>;

/**
* Link a Request ID to this client
* @param args
*/
link(...args: any[]): Promise<LinkMessage>;

/**
* Wait for a desciption signal
* @param args
*/
signal(...args: any[]): Promise<string>;

/**
* Terminate the signaling session
*/
close(): void


/**
* Listen to Interface events
* @param args
*/
on(...args: any[]): void;

/**
* Emit an event to the interface
* @param channel
* @param callback
*/
emit(channel: string, callback: (...args: any[])=>void)

}
```
22 changes: 22 additions & 0 deletions clients/liquid-auth-client-js/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"parserOptions": {
"project": "tsconfig.json",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint/eslint-plugin",
"eslint-plugin-tsdoc"
],
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"rules": {
"@typescript-eslint/no-explicit-any": "warn"
}
}
1 change: 1 addition & 0 deletions clients/liquid-auth-client-js/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
lib
docs

# Logs
logs
Expand Down
4 changes: 4 additions & 0 deletions clients/liquid-auth-client-js/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}
Loading

0 comments on commit 0a37622

Please sign in to comment.