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

Feat/connect rtc #8

Merged
merged 24 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f0293a4
docs: add webrtc decision
PhearZero Feb 15, 2024
0c7a935
feat: session status and webvitals performance increase
PhearZero Feb 15, 2024
77353cd
feat: WebRTC with websocket signaling
PhearZero Mar 25, 2024
9683478
fix: session adapter
PhearZero Apr 9, 2024
6396c36
wip: adds basic message passing demo
PhearZero Apr 10, 2024
785b999
Merge branch 'refs/heads/develop' into feat/connect-rtc
PhearZero Apr 10, 2024
da647ae
fix: test stubs
PhearZero Apr 10, 2024
fb021a4
test: add signals unit tests
PhearZero Apr 10, 2024
1d88a24
refactor: add core module and enforce style guides
PhearZero Apr 11, 2024
d1a61e0
chore: cleanup docker files
PhearZero Apr 11, 2024
1515c14
Merge branch 'refs/heads/feat/rekeyed-account-support' into feat/conn…
PhearZero Apr 11, 2024
9203910
chore: cleanup demo application
PhearZero Apr 12, 2024
102a55c
test: enforce linters and tests
PhearZero Apr 15, 2024
9ce32c4
Merge remote-tracking branch 'refs/remotes/origin/develop' into feat/…
PhearZero Apr 15, 2024
8d2f3f3
build: remove preinstall hooks
PhearZero Apr 15, 2024
6c6a257
refactor: change call to offer
PhearZero Apr 17, 2024
68e6cab
test: add signaling fixture for session
PhearZero Apr 18, 2024
af6b7e7
feat: js signaling client
PhearZero Apr 18, 2024
e98cedd
chore: lint fixes
PhearZero Apr 18, 2024
d59ff07
docs: update contrib and top level compose
PhearZero Apr 22, 2024
6cc3eef
fix: patch service for docker
PhearZero Apr 22, 2024
325edae
build: add ngrok to docker
PhearZero Apr 22, 2024
3e34494
docs: cleanup config docs
PhearZero Apr 22, 2024
ce75747
chore: cleanup files and update README
PhearZero Apr 22, 2024
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
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?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we enforce it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could if we remove the STUN/TURN servers but we would lose a decent percentage of devices behind symmetric NAT

Copy link
Collaborator

@kylebeee kylebeee Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is enforced locality even possible if apple / chrome sync passkeys across devices?

Not sure about chrome but apple really doesn't adhere to the standard well

https://www.slashid.dev/blog/passkeys-deepdive/#:~:text=Passkeys%20and%20traditional%20platform%20authenticator,event%20of%20a%20device%20compromise.

"impossible to verify the device type used to generate a key, and hence the trustworthiness of the key and its metadata. In fact, the lack of an attestation statement means that you can’t prove the key has been stored, or even generated, safely because you can’t infer properties/provenance of the authenticator."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kylebeee Enforcing locality of the WebRTC peer channel, limiting discovery to only local addresses (no STUN/TURN)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the decision is no enforcing locality we should remove this bullet IMO


## 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
Loading