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

feature/client-typescript #25

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5db35ec
Rename .js files to .ts
MasterKale Jan 7, 2020
1cc3066
Install TS support for babel
MasterKale Jan 7, 2020
36dab6f
Configure Babel with Typescript preset
MasterKale Jan 7, 2020
789aacc
Add tsconfig.json
MasterKale Jan 7, 2020
0a773bc
Update Webpack config to load .ts files
MasterKale Jan 7, 2020
5076da1
Fix trailing comma in tsconfig
MasterKale Jan 7, 2020
ecb763c
Install Typescript as dev dependency
MasterKale Jan 7, 2020
52e45d6
Add vendor.d.ts
MasterKale Jan 7, 2020
640c697
Add typing to publicKeyCredentialToJSON()
MasterKale Jan 7, 2020
22e8464
Add stronger typing to publicKeyCredentialToJSON()
MasterKale Jan 7, 2020
a9d6af1
Refine typings in util.ts
MasterKale Jan 7, 2020
f0dd6d7
Add util function for base64-to-buffer
MasterKale Jan 7, 2020
b841e2a
Handle potentially null userHandle during login
MasterKale Jan 7, 2020
6b12c10
Update registration methods with typings
MasterKale Jan 7, 2020
d9387e9
Update solveLoginChallenge with stronger typing
MasterKale Jan 7, 2020
e0e94b2
Update tsconfig.json to only emit declarations
MasterKale Jan 7, 2020
07a25ab
Clean up typings in utils
MasterKale Jan 7, 2020
f8a7f18
Export more interfaces
MasterKale Jan 7, 2020
ce0c81d
Allow for optional allowCredentials from server
MasterKale Jan 7, 2020
3300f88
Update solve methods to use renamed util method
MasterKale Jan 7, 2020
8e2847d
Add typings and tsc declaration emission to build
MasterKale Jan 7, 2020
5e03c3f
Split up credential-to-JSON methods
MasterKale Jan 7, 2020
03b2f46
Add object rest spread plugin
MasterKale Jan 7, 2020
900c974
Remove babel config from Webpack for .babelrc
MasterKale Jan 7, 2020
29e95e3
Swap out Babel for ts-loader
MasterKale Jan 7, 2020
cfa59e8
Bump down TS target to ES2015
MasterKale Jan 8, 2020
a787937
Fix PublicKeyCredential not spreading values
MasterKale Jan 8, 2020
b1e6472
Bump up TS target to ES2018
MasterKale Jan 8, 2020
7ed940f
Delete yarn.lock
MasterKale Jan 8, 2020
fcd12ab
Also export challenge response JSON interfaces
MasterKale Jan 8, 2020
c7a3655
Update README to make it specific to this library
MasterKale Jan 8, 2020
f7379d2
Fix README path to front end example
MasterKale Jan 8, 2020
9ec9bf8
Add in missing slash from example path
MasterKale Jan 8, 2020
2daf219
Revert "Delete yarn.lock"
MasterKale Jan 23, 2020
6c1c4de
Remove package-lock.json
MasterKale Jan 23, 2020
c106ec1
Remove package yarn.lock files
MasterKale Feb 4, 2020
add8b92
Add package-lock.json to gitignore
MasterKale Feb 4, 2020
8104884
Update primary yarn.lock file
MasterKale Feb 4, 2020
a5a5252
Fix misspelling in client README.md
MasterKale Feb 4, 2020
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
**/node_modules/
dist
dist
package-lock.json
64 changes: 10 additions & 54 deletions packages/client/README.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,29 @@
# webauthn
# @webauthn/client

Implementation of strong authentication with the webauthn standard and FIDO2.
Strong authentication is an authentication method using a physical key.
This library contains convenience methods intended to simplify interactions with a browser's Webauthn API.

For a more thorough introduction see these two nice articles:

- [introduction](https://medium.com/@herrjemand/introduction-to-webauthn-api-5fd1fb46c285)
- [verifying fido2 responses](https://medium.com/@herrjemand/verifying-fido2-responses-4691288c8770)
This front end library complements this repo's [@webauthn/server](../server/) NodeJS library.

## Installation

```js
npm install @webauthn/client
npm install @webauthn/server
```

## usage

`Webauthn` is composed of two parts `@webauthn/client` and `@webauthn/server`

### On the browser
## Usage

```js
import {
import {
solveRegistrationChallenge,
solveLoginChallenge
} from '@webauthn/client';
```

- `solveRegistrationChallenge`:
convert the challenge returned by the server on the register route into the response to be returned
- `solveLoginChallenge`:
convert the challenge returned by the server on the login route into the response to be returned

See an example in example/front

### On the server

```js
import {
parseRegisterRequest,
generateRegistrationChallenge,
parseLoginRequest,
generateLoginChallenge,
verifyAuthenticatorAssertion,
} from '@webauthn/server';
```

- `parseRegisterRequest`:
Extract challenge and key from the register request body. The challenge allow to retrieve the user, and the key must be stored server side linked to the user.
- `generateRegistrationChallenge`:
Generate a challenge from a relying party and a user `{ relyingParty, user }` to be sent back to the client, in order to register
- `parseLoginRequest`:
Extract challenge and KeyId from the login request.
- `generateLoginChallenge`:
Generate challengeResponse from the key sent by the client during login. challengeResponse.challenge should be stored serverside linked to the corresponding user
- `verifyAuthenticatorAssertion`:
Take the loginChallenge request body and the key stored with the user, and return true if it passes the authenticator assertion

See an example in example/server


## Roadmap

For now only fido-u2f and packed format are implemented

- Implement android-key format
- Implement android-safetynet format
- Implement tpm format
- `solveRegistrationChallenge`: convert the challenge returned by the server on the register route into the response to be returned
- `solveLoginChallenge`: convert the challenge returned by the server on the login route into the response to be returned

See an example in [example/front](../../example/front/).

## TypeScript support

This client library's source files are 100% TypeScript. As a result every method is fully typed and supports use in both JavaScript and TypeScript projects.
8 changes: 3 additions & 5 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "@webauthn/client",
"version": "0.1.3",
"main": "dist/main.js",
"types": "dist/index.d.ts",
"module": "src/index.js",
"repository": {
"type": "git",
Expand All @@ -14,15 +15,12 @@
},
"license": "Apache-2.0",
"dependencies": {
"core-js": "^3.3.2",
"regenerator-runtime": "^0.13.3",
"unibabel": "^2.1.7",
"webpack": "^4.30.0"
},
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"babel-loader": "^8.0.6",
"ts-loader": "^6.2.1",
"typescript": "^3.7.4",
"webpack-cli": "^3.3.1"
}
}
2 changes: 0 additions & 2 deletions packages/client/src/index.js

This file was deleted.

8 changes: 8 additions & 0 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export {
solveRegistrationChallenge,
RegistrationChallengeJSON,
} from './solveRegistrationChallenge';
export {
solveLoginChallenge,
LoginChallengeJSON,
} from './solveLoginChallenge';
25 changes: 0 additions & 25 deletions packages/client/src/solveLoginChallenge.js

This file was deleted.

49 changes: 49 additions & 0 deletions packages/client/src/solveLoginChallenge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import  { assertionToJSON, AssertionCredential, stringToBuffer, AssertionCredentialJSON } from './utils';

/**
* JSON representation of an allowed Webauthn credential
*/
export interface AllowedCredentialJSON extends Omit<PublicKeyCredentialDescriptor, 'id'> {
id: string; // A base64-encoded Buffer
}

/**
* JSON-ified options to be passed into navigator.credentials.get(). These values are requested
* from the Relying Party (see `server > generateLoginChallenge()`), which responds with JSON
* containing ArrayBuffers converted to base64-encoded strings.
*/
export interface LoginChallengeJSON extends Omit<PublicKeyCredentialRequestOptions, 'challenge' | 'allowCredentials'> {
challenge: string; // A base64-encoded Buffer
allowCredentials?: AllowedCredentialJSON[];
}

/**
* Convert JSON-ified credential options into values for use in navigator.credentials.get()
*/
function loginChallengeToPublicKey (challenge: LoginChallengeJSON): PublicKeyCredentialRequestOptions {
let allowCredentials: PublicKeyCredentialDescriptor[];
if (Array.isArray(challenge.allowCredentials) && challenge.allowCredentials.length > 0) {
allowCredentials = challenge.allowCredentials.map(allowCredential => ({
...allowCredential,
id: stringToBuffer(allowCredential.id),
}));
}

return {
...challenge,
challenge: stringToBuffer(challenge.challenge),
// @ts-ignore 2454
allowCredentials,
};
};

/**
* Initiate the Webauthn Assertion process, then convert the results to JSON to POST back to the
* Relying Party (see `server > parseLoginRequest()`)
*/
export async function solveLoginChallenge (challenge: LoginChallengeJSON): Promise<AssertionCredentialJSON> {
const publicKey = loginChallengeToPublicKey(challenge);
const credential = (await navigator.credentials.get({ publicKey }) as AssertionCredential);

return assertionToJSON(credential);
};
27 changes: 0 additions & 27 deletions packages/client/src/solveRegistrationChallenge.js

This file was deleted.

40 changes: 40 additions & 0 deletions packages/client/src/solveRegistrationChallenge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { attestationToJSON, AttestationCredential, stringToBuffer } from './utils';

/**
* JSON-ified options to be passed into navigator.credentials.create(). These values are requested
* from the Relying Party (see `server > generateRegistrationChallenge()`), which responds with JSON
* containing ArrayBuffers converted to base64-encoded strings.
*/
export interface RegistrationChallengeJSON extends Omit<PublicKeyCredentialCreationOptions, 'challenge' | 'user'> {
challenge: string; // A base64-encoded Buffer
user: {
id: string; // A base64-encoded Buffer
displayName: string;
name: string;
},
}

/**
* Convert JSON-ified credential options into values for use in navigator.credentials.create()
*/
export function registrationChallengeToPublicKey (challenge: RegistrationChallengeJSON): PublicKeyCredentialCreationOptions {
return {
...challenge,
challenge: stringToBuffer(challenge.challenge),
user: {
...challenge.user,
id: stringToBuffer(challenge.user.id),
},
};
}

/**
* Initiate the Webauthn Attestation process, then convert the results to JSON to POST back to the
* Relying Party (see `server > parseRegisterRequest()`)
*/
export async function solveRegistrationChallenge (challenge: RegistrationChallengeJSON) {
const publicKey = registrationChallengeToPublicKey(challenge);
const credential = (await navigator.credentials.create({ publicKey }) as AttestationCredential);

return attestationToJSON(credential);
}
26 changes: 0 additions & 26 deletions packages/client/src/utils.js

This file was deleted.

Loading