Giter VIP home page Giter VIP logo

webauthn-json's Introduction

@github/webauthn-json

@github/webauthn-json is a client-side Javascript library that serves as convenience wrapper for the the WebAuthn API by encoding binary data using base64url (also known as "websafe" or "urlsafe" base64).

The WebAuthn API itself takes input and output values that look almost like JSON, except that binary data is represented as ArrayBuffers. Using webauthn-json allows the data to be sent from/to the server as normal JSON without any custom client-side processing. This will be possible directly in the browser some day, but we're here for you until then.

Usage

  1. Replace calls:
  • navigator.credentials.create(...) with create(parseCreationOptionsFromJSON(...)).
  • navigator.credentials.get(...) with get(parseRequestOptionsFromJSON(...)).
  1. Encode/decode binary values on the server as base64url.

Example

Install using:

npm install --save @github/webauthn-json

Then:

import {
  create,
  parseCreationOptionsFromJSON,
} from "@github/webauthn-json/browser-ponyfill";

const request = fetch("...");

async function createCredential() {
  const json = await (await request).json();
  const options = parseCreationOptionsFromJSON(json);
  const response = await create(options);
  fetch("...", {
    method: "POST",
    body: JSON.stringify(response),
  });
}

See here for fully working client-side demo code.

API (browser ponyfill)

We now recommend using a ponyfill for the new JSON-based APIs in the WebAuthn spec:

// @github/webauthn-json/browser-ponyfill

function supported(): boolean;

function parseCreationOptionsFromJSON(json: JSON): CredentialCreationOptions;
function parseRequestOptionsFromJSON(json: JSON): CredentialRequestOptions;

// You can call `.toJSON()` on the result or pass directly to `JSON.stringify()`.
function create(options: CredentialCreationOptions): Promise<PublicKeyCredential>;
// You can call `.toJSON()` on the result or pass directly to `JSON.stringify()`.
function get(options: CredentialRequestOptions): Promise<PublicKeyCredential>;

API (main library)

This was the original simplified API, which remains supported.

// @github/webauthn-json

function create(requestJSON: JSON): Promise<JSON>;
function get(requestJSON: JSON): Promise<JSON>;
function supported(): boolean;

Schema

There are are several ways to encode JSON with binary fields. @github/webauthn-json focuses on one simple approach: converting the known structure using a simple (custom) schema format. @github/webauthn-json uses a few tricks for a compact schema encoding: the main build is about โ‰ˆ1KB when minified and gzipped (although we publish unminified builds).

Right now, we only convert fields explicitly known to be used by the WebAuthn API. This means that you'll have to update to a newer version of this library if you want to use new fields in the future.

To print the current schema, run:

npx @github/webauthn-json schema

Extensions

Modern browsers generally only support โ€” and most sites only need to use โ€” a small number of extensions. To save code size, @github/webauthn-json only includes the following extensions by default:

In addition, we handle the following info (that is not technically part of extensions):

If you need to convert additional input or output extensions, use either of the following:

  • createExtended() and getExtended() from @github/webauthn-json/extended.
  • parseExtendedCreationOptionsFromJSON() and parseExtendedRequestOptionsFromJSON() from @github/webauthn-json/browser-ponyfill/extended.

Contributions

The scope of @github/webauthn-json is fairly small โ€” it's essentially feature-complete. However, we're happy to accept issues or pull requests that address the core goal of the project!

Footnotes

  1. This comes from getTransports() on the AuthenticatorAttestationResponse. Note that we don't include its three sibling functions (getAuthenticatorData(), getPublicKey(), and getPublicKeyAlgorithm()), since they duplicates information that is available in other parts of the response. In particular, the authenticator data is available inside the signed attestation object. โ†ฉ

webauthn-json's People

Contributors

abhineet97 avatar bdehamer avatar cuu508 avatar cybai avatar dependabot[bot] avatar emlun avatar feelepxyz avatar fredeil avatar koddsson avatar kyfast avatar lgarron avatar santiagorodriguez96 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webauthn-json's Issues

Usage of this library with Flask

Hi there!

I want to use this library with Flask, but I am unable to do so. Could you give a minimum viable example of how to include this library if one wasnโ€™t using Typescript or Node JS?

Essentially, I want to be able to use this library in a single html file with a script tag in there. But after several hours of trying, I couldnโ€™t figure it out.

Any help?

Restore typings for the extended build

We're on Parcel 2, which currently has issues building types for multiple targets:

parcel-bundler/parcel#5010

I'd like to restore these as soon as practical. If that doesn't work with Parcel, a workaround might be to rewrite the package.json temporarily, or use a package.json file in a subfolder.

Include rollup in releases

It would be helpful if the dist/ directory created by rollup were included in each release. Currently, I have to run rollup manually after each release.

Use shorter code for `base64url.ts`

base64urlToBuffer() and bufferToBase64url() take up a significant part of the build size. It would be nice to make them as small as possible. I believe there are shorter implementations we could use, especially taking into account that the expected data is only on the order of a hundred bytes.

Note that the minified code size matters the most (not the source code size)!

Bundling errors under yarn3 after upgrade from `0.5.7` to `0.6.2`

$ yarn dlx -q envinfo --preset jest

  System:
    OS: Linux 5.11 Ubuntu 21.10 21.10 (Impish Indri)
    CPU: (12) x64 Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
  Binaries:
    Node: 16.13.1 - /tmp/xfs-705ba6ea/node
    Yarn: 3.2.0-rc.5 - /tmp/xfs-705ba6ea/yarn
$ yarn why @github/webauthn-json
โ””โ”€ xxx@packages/xxx
   โ””โ”€ @github/webauthn-json@npm:0.6.2 (via npm:0.6.2)
webpack@npm:5.66.0
typescript@patch:typescript@npm%3A4.5.4#~builtin<compat/typescript>::version=4.5.4&hash=493e53
ERROR in ./packages/xxx/lib/fido.tsx 17:0-46
Module not found: Error: Can't resolve '@github/webauthn-json' in '/path/to/packages/xxx/lib'
resolve '@github/webauthn-json' in '/path/to/packages/xxx/lib'
  Parsed request is a module
  using description file: /path/to/packages/xxx/package.json (relative path: ./lib)
    Field 'browser' doesn't contain a valid alias configuration
    resolve as module
      resolved by pnp to /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/
        using description file: /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/package.json (relative path: .)
          using exports field: ./dist/webauthn-json.js
            using description file: /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/package.json (relative path: ./dist/webauthn-json.js)
              no extension
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js doesn't exist
              .ts
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js.ts doesn't exist
              .tsx
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js.tsx doesn't exist
              .js
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js.js doesn't exist
              .mjs
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js.mjs doesn't exist
              .cjs
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js.cjs doesn't exist
              .ejs
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js.ejs doesn't exist
              .jsx
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js.jsx doesn't exist
              .json
                Field 'browser' doesn't contain a valid alias configuration
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js.json doesn't exist
              as directory
                /path/to/.yarn/cache/@github-webauthn-json-npm-0.6.2-4bf1caaf04-a10c7a9e5a.zip/node_modules/@github/webauthn-json/dist/webauthn-json.js doesn't exist

Webpack bundling broken after version 0.5.0

Bundling @github/webauthn-json in a Webpack project broke in version 0.5.0. I'm guessing related to the Parcel 2 change. The following error is thrown when trying to import @github/webauthn-json.

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ~/projects/test/node_modules/@github/webauthn-json/dist/main/webauthn-json.js
require() of ES modules is not supported.
require() of ~/projects/test/node_modules/@github/webauthn-json/dist/main/webauthn-json.js from ~/projects/test/.next/server/pages/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename webauthn-json.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from ~/projects/test/node_modules/@github/webauthn-json/package.json.
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1154:13)
    at Module.load (internal/modules/cjs/loader.js:986:32)
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)
    at Module.require (internal/modules/cjs/loader.js:1026:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at eval (webpack-internal:///@github/webauthn-json:1:18)
    at Object.@github/webauthn-json (~/projects/test/.next/server/pages/index.js:175:1)
    at __webpack_require__ (~/projects/test/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./src/client/register.ts:3:79)
    at Module../src/client/register.ts (~/projects/test/.next/server/pages/index.js:152:1) {
  code: 'ERR_REQUIRE_ESM'
}

type export in version 0.6

In version 0.5 we used

import {
  PublicKeyCredentialDescriptorJSON,
  PublicKeyCredentialWithAssertionJSON,
  PublicKeyCredentialWithAttestationJSON,
} from '@github/webauthn-json';

After upgrading to 0.6, the last two types were found along a different path: @github/webauthn-json/extended.

The third type PublicKeyCredentialDescriptorJSON is only exported from @github/webauthn-json/dist/types/basic/json, which looks wrong.

Is this type not meant to be accessed externally, or is there something wrong in the type declaration?

backend equivlent

Hi there,
Is there a companion webauth json for the server side or a tutorial you could recommend?

Use base64url instead

FIDO Alliance has a convention to use base64url. This is what we use for our conformance testing API, and for all our documentation.

NextJS App Router - Server-Side Compatibility

Hello,

I'm looking to use this library in my NextJS app router project. Is there any way to make and use this library to be server-side environment compatible?

This library is client-side per the description: @github/webauthn-json is a client-side Javascript library, however, the application logic for WebAuthN authentication is server-side, so the usage is currently not usable.

Package subpath is not defined by exports

I'm running in to this error: Error: Package subpath './browser-ponyfill' is not defined by "exports" in /<project_path>/node_modules/@github/webauthn-json/package.json when using the latest 2.0.2 version with the following import:

Error: Package subpath './browser-ponyfill' is not defined by "exports" in /<project_path>/node_modules/@github/webauthn-json/package.json

I'm a bit unclear if this is something I'm doing wrong or if there's a particular version I need to be using to avoid this issue. It looks like it does exist here: https://github.com/github/webauthn-json/blob/main/package.json#L23-L25

Any help would be much appreciated!

Not getting "clientExtensionResults" key in the output of get() and create() methods

Hi there!

In the documentation, it states that:

Modern browsers generally only support a single extension: the appid string. If you need to convert additional input or output extensions, use createExtended() and getExtended() from @github/webauthn-json/dist/extended (or @github/webauthn-json/dist/extended.esm).

So, If I understood correctly, I should be able to use the appid extension with the default create() and get() methods.

However, when I pass the extension in the credential options to those methods, I don't get the clientExtensionResults in the output.

I can go ahead and try to make it that clientExtensionResults are returned just as it's done for the extended module If you agree with this ๐Ÿ™‚

Error on compilation

I'm getting:
ERROR in node_modules/@github/webauthn-json/dist/types/basic/api.d.ts(2,92): error TS2304: Cannot find name 'CredentialCreationOptions'.
| node_modules/@github/webauthn-json/dist/types/basic/api.d.ts(3,58): error TS2304: Cannot find name 'PublicKeyCredential'.
| node_modules/@github/webauthn-json/dist/types/basic/api.d.ts(5,88): error TS2304: Cannot find name 'CredentialRequestOptions'.

And also:
ERROR in ../node_modules/@github/webauthn-json/dist/types/browser-ponyfill.d.ts:5:1 - error TS1128: Declaration or statement expected.

Cannot get Face ID option in IOS Safari

Hi,

When I run the demo on IOS Safari and click register, safari shows a pop-up
"Do you want to allow "github.github.com" to use Face ID?"

But when I try the same option on my website it shows
"Do you want to save a passkey for "test"?

furthermore, in your demo when I click "Other Options"
It shows the first option as Face ID.
On my website, it shows "Passkey in iCloud Keychain.

I did not recognize the difference in your demo. to show Face ID option.

Browser-global extended distribution variant missing

Hi all,

during a recent project we wanted to use the browser-global dist version but noticed it is only exported in the basic and not the extended variant. Therefore, we'd like to ask whether you would be interested in adding that version to the script/build-js.js. As we've already done that in our fork to get our project to work, I've also just submitted a small PR (#60) for that in case you want to take a look ๐Ÿ™‚

How can I access the attestationObject?

Sorry if this is straightforward and I've missed the explanation in the documentation, but I am unsure how to decode the attestationObject on my server. I was able to decode the clientDataObject with Buffer.from(credential.response.clientDataJSON, 'base64url').toString('ascii') but the same doesn't seem to work with the attestationObject. It appears the attestationObject is also CBOR encoded. So, I tried decoding from base64url and then from CBOR but that didn't work. Anyway, I'd appreciate any help I can get here. Thanks in advance!

Typescript 4.9.4: Types of property 'authenticatorAttachment' are incompatible

With Typescript 4.9.4, I am getting the following error. With TS 4.8.4, no such error is thrown.

node_modules/@github/webauthn-json/dist/types/basic/json.d.ts:9:18 - error TS2430: Interface 'PublicKeyCredentialWithClientExtensionResults' incorrectly extends interface 'PublicKeyCredential'.
  Types of property 'authenticatorAttachment' are incompatible.
    Type 'string | null | undefined' is not assignable to type 'string | null'.
      Type 'undefined' is not assignable to type 'string | null'.

Compilation error while using get

Hello,

I am running into this compilation error, while trying to use navigate.credentials.get. Is this an issue or I am missing something?

 tsc --noEmit
node_modules/@github/webauthn-json/src/webauthn-json/base64url.ts:28:26 - error TS2569: Type 'Uint8Array' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.

28   for (const charCode of byteView) {
                            ~~~~~~~~


Found 1 error.

tsc --version
Version 4.5.5

I am using it as below in my ts project:

      const options = parseRequestOptionsFromJSON({
        publicKey: {
          challenge: securityKeyChallengeResponse.challenge,
          timeout: 60000,
          rpId: securityKeyChallengeResponse.rp.id,
          allowCredentials: securityKeyChallengeResponse.allowedCredentials,
        },
      });

      const securityKeyCredential = await get(options);
      const securityKeyCredentialJson = securityKeyCredential.toJSON();

Compatibility with TypeScript 3.6

Hey @lgarron, it looks like most of @types/webappsec-credential-management has now been upstreamed into TypeScript's own lib/lib.dom.d.ts. See microsoft/TypeScript@b963e1a.

Trying to use webauthn-json on TypeScript 3.6 leads to the following error:

node_modules/@types/webappsec-credential-management/index.d.ts(378,6): error TS2300: Duplicate identifier 'PublicKeyCredentialType'.
node_modules/@types/webappsec-credential-management/index.d.ts(383,6): error TS2300: Duplicate identifier 'UserVerificationRequirement'.
node_modules/@types/webappsec-credential-management/index.d.ts(394,5): error TS2717: Subsequent property declarations must have the same type.  Property 'extensions' must be of type 'AuthenticationExtensionsClientInputs | undefined', but here has type 'any'.
node_modules/@types/webappsec-credential-management/index.d.ts(401,5): error TS2687: All declarations of 'id' must have identical modifiers.
node_modules/@types/webappsec-credential-management/index.d.ts(401,5): error TS2717: Subsequent property declarations must have the same type.  Property 'id' must be of type 'string | undefined', but here has type 'string'.
node_modules/@types/webappsec-credential-management/index.d.ts(425,6): error TS2300: Duplicate identifier 'AuthenticatorTransport'.
node_modules/@types/webappsec-credential-management/index.d.ts(439,6): error TS2300: Duplicate identifier 'AuthenticatorAttachment'.
node_modules/@types/webappsec-credential-management/index.d.ts(453,6): error TS2300: Duplicate identifier 'AttestationConveyancePreference'.
node_modules/@types/webappsec-credential-management/index.d.ts(469,5): error TS2717: Subsequent property declarations must have the same type.  Property 'extensions' must be of type 'AuthenticationExtensionsClientInputs | undefined', but here has type 'any'.
node_modules/@types/webappsec-credential-management/index.d.ts(501,14): error TS2717: Subsequent property declarations must have the same type.  Property 'response' must be of type 'AuthenticatorResponse', but here has type 'AuthenticatorAssertionResponse | AuthenticatorAttestationResponse'.
node_modules/typescript/lib/lib.dom.d.ts(1125,5): error TS2687: All declarations of 'id' must have identical modifiers.
node_modules/typescript/lib/lib.dom.d.ts(11992,11): error TS2320: Interface 'PublicKeyCredential' cannot simultaneously extend types 'Credential' and 'CredentialData'.
  Named property 'id' of types 'Credential' and 'CredentialData' are not identical.
node_modules/typescript/lib/lib.dom.d.ts(19991,6): error TS2300: Duplicate identifier 'AttestationConveyancePreference'.
node_modules/typescript/lib/lib.dom.d.ts(19994,6): error TS2300: Duplicate identifier 'AuthenticatorAttachment'.
node_modules/typescript/lib/lib.dom.d.ts(19995,6): error TS2300: Duplicate identifier 'AuthenticatorTransport'.
node_modules/typescript/lib/lib.dom.d.ts(20060,6): error TS2300: Duplicate identifier 'PublicKeyCredentialType'.
node_modules/typescript/lib/lib.dom.d.ts(20116,6): error TS2300: Duplicate identifier 'UserVerificationRequirement'.

I wonder how we best resolve this? Should we just remove the dependency for @types/webappsec-credential-management?

CC: @web-systems

Add `prf` extension

w3c/webauthn#1732 re-added this: https://w3c.github.io/webauthn/#prf-extension

We need to add support here:

const authenticationExtensionsClientInputsSchema: Schema = {
appid: optional(copyValue),
appidExclude: optional(copyValue),
uvm: optional(copyValue),
credProps: optional(copyValue),
largeBlob: optional({
support: optional(copyValue),
read: optional(copyValue),
write: optional(convertValue),
}),
};
const authenticationExtensionsClientOutputsSchema: Schema = {
appid: optional(copyValue),
appidExclude: optional(copyValue),
uvm: optional(copyValue),
credProps: optional(copyValue),
largeBlob: optional({
supported: optional(copyValue),
blob: optional(convertValue),
written: optional(copyValue),
}),
};

interface ExtendedExtensionsClientInputsJSON {
appid?: string;
appidExclude?: string;
uvm?: boolean;
credProps?: boolean;
largeBlob?: {
support?: "required" | "preferred";
read?: boolean;
write?: Base64urlString;
};
}
interface ExtendedAuthenticationExtensionsClientOutputsJSON {
appid?: boolean;
appidExclude?: boolean;
uvm?: Array<[number, number, number]>;
credProps?: {
rk: boolean;
};
largeBlob?: {
supported?: boolean;
blob?: Base64urlString;
written?: boolean;
};
}

Jest encountered an unexpected token

I'm writing a test using Jest and I encountered below error. Seem that Jest cannot parse webauthn-json.

 FAIL  front/shared/pages/credentialSettings/credentialSettings.spec.tsx
  โ— Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     โ€ข To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     โ€ข If you need a custom transformation specify a "transform" option in your config.
     โ€ข If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    ~/node_modules/@github/webauthn-json/dist/main/webauthn-json.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){function e(e){const t="==".slice(0,(4-e.length%4)%4),n=e.replace(/-/g,"+").replace(/_/g,"/")+t,r=atob(n),o=new ArrayBuffer(r.length),c=new Uint8Array(o);for(let e=0;e<r.length;e++)c[e]=r.charCodeAt(e);return o}function t(e){const t=new Uint8Array(e);let n="";for(const e of t)n+=String.fromCharCode(e);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function n(e,t,r){if("copy"===t)return r;if("convert"===t)return e(r);if(t instanceof Array)return r.map((r=>n(e,t[0],r)));if(t instanceof Object){const o={};for(const[c,i]of Object.entries(t))if(c in r)null!=r[c]?o[c]=n(e,i.schema,r[c]):o[c]=null;else if(i.required)throw new Error("Missing key: "+c);return o}}function r(e){return{required:!0,schema:e}}function o(e){return{required:!1,schema:e}}const c={type:r("copy"),id:r("convert")

    SyntaxError: Unexpected token export



      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
      at Object.<anonymous> (front/shared/pages/credentialSettings/CredentialUtils.tsx:729:25)

Here is my jest.config.js:

module.exports = {
  verbose: true,
  preset: 'jest-puppeteer',
  transformIgnorePatterns: ['<rootDir>/node_modules/'],
  transform: {
    '^.+\\.(ts|tsx)$': 'ts-jest',
    '^.+\\.(js|jsx)$': 'babel-jest',
    '^.+\\.svg$': '<rootDir>/svgTransform.js',
  },
  setupFilesAfterEnv: ['<rootDir>/front/test/setupTests.js'],
  testMatch: ['<rootDir>/front/**/?(*.)+(spec).ts?(x)'],
  moduleNameMapper: {
    '.+\\.(png|jpg|ttf|woff|woff2)$': 'identity-obj-proxy',
    '.+\\.(css|styl|less|sass|scss)$': '<rootDir>/front/test/styleMock.js',
  },
  reporters: ['default', 'jest-junit'],
  testEnvironment: 'jsdom',
};

Here is my config for babel:

{
  "env": {
    "test": {
      "plugins": [
        "transform-es2015-modules-commonjs"
      ]
    }
  }
}

I'm using Jest 24.9.0, webauthn-json version 0.5.7, my setup is React as frontend with Jest for frontend test and Rails as backend.

This could be an issue with Jest, sorry if I ask in wrong place ๐Ÿ™ ๐Ÿ™ ๐Ÿ™
Just want to see that if any one has any idea with my setup.

Unable to import createExtended() and getExtended() methods from webauthn-json/extended

Hi there! Thank you for your work on this!

I'm trying to use the createExtended() and getExtended() methods, but I'm unable to import them using import { createExtended, getExtended } from '@github/webauthn-json/extended'.
I'm using version 0.4.1 of this package.
The error I'm getting is:

Screen Shot 2020-06-03 at 2 38 40 PM

According to the documentation importing from @github/webauthn-json/extended should work but it seems that this file does not exist in node_modules after installing the last version.

Crash on mobile browser

When using any of the create or get functions everything works ok on desktop, but mobile chrome browser crashes (exits/closes).

Using the demo provided here works as expected, but when integrating (even a copy of the demo!) inside a vue application, I get the above behavior.

Sample component (literally copy pasted the demo code inside an empty Vue component):

<template>
  <button id="register">Register<span class="status"></span></button>
  <button id="authenticate">Authenticate<span class="status"></span></button>
  <button id="clear">Clear<span class="status"></span></button>
  <button id="supported">supported()<span class="status"></span></button>

  <textarea
    id="registrations"
    spellcheck="false"
    placeholder="localStorage.webauthnExampleRegistrations"
    title="localStorage.webauthnExampleRegistrations"
  ></textarea>

  <textarea
    id="error"
    spellcheck="false"
    placeholder="Errors will be logged here."
  ></textarea>
</template>

<script>
import {create,get,supported} from "@github/webauthn-json"

function getRegistrations() {
  const registrations = JSON.parse(
    localStorage.webauthnExampleRegistrations || "[]",
  );
  return registrations;
}

function setRegistrations(
  registrations,
) {
  localStorage.webauthnExampleRegistrations = JSON.stringify(
    registrations,
    null,
    "  ",
  );
  displayRegistrations();
}

function saveRegistration(
  registration,
) {
  const registrations = getRegistrations();
  registrations.push(registration);
  setRegistrations(registrations);
}

function registrationElem() {
  return document.querySelector("#registrations");
}

function displayRegistrations() {
  registrationElem().value = JSON.stringify(getRegistrations(), null, "  ");
}

function withStatus(selector, fn) {
  return async function () {
    document.querySelector("#error").textContent = "";
    document.querySelector(selector).textContent = "โ€ฆ";
    try {
      await fn();
      document.querySelector(selector).textContent = " โœ…";
    } catch (e) {
      document.querySelector(selector).textContent = " โŒ";
      console.error(e);
      document.querySelector("#error").textContent = e;
    }
  };
}

function registeredCredentials() {
  return getRegistrations().map((reg) => ({
    id: reg.rawId,
    type: reg.type,
  }));
}

async function register() {
  saveRegistration(
    await create({
      publicKey: {
        challenge: "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
        rp: { name: "Localhost, Inc." },
        user: {
          id: "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII",
          name: "test_user",
          displayName: "Test User",
        },
        pubKeyCredParams: [{ type: "public-key", alg: -7 }],
        excludeCredentials: registeredCredentials(),
        authenticatorSelection: { userVerification: "discouraged" },
        extensions: {
          credProps: true,
        },
      },
    }),
  );
}

async function authenticate() {
  await get({
    publicKey: {
      challenge: "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
      allowCredentials: registeredCredentials(),
      userVerification: "discouraged",
    },
  });
}

async function clear() {
  setRegistrations([]);
}

async function testSupported() {
  document.querySelector("#supported .status").textContent = "โ€ฆ";
  document.querySelector("#supported .status").textContent = supported()
    ? " โœ…"
    : " โŒ";
}

export default {
  name: 'Home',
  mounted() {
    try {
      document
        .querySelector("#register")
        .addEventListener("click", withStatus("#register .status", register));
      document
        .querySelector("#authenticate")
        .addEventListener(
          "click",
          withStatus("#authenticate .status", authenticate),
        );
      document
        .querySelector("#clear")
        .addEventListener("click", withStatus("#clear .status", clear));
      document
        .querySelector("#supported")
        .addEventListener("click", testSupported);
    } catch (e) {
      console.error(e);
    }
  }
}
</script>

Reproducible on an Android Redmi Note 7 device, with Chrome version 88.0.4324.181

Expose `AuthenticatorResponse` methods?

Chrome 85 is adding:

  • getPublicKey()
  • getPublicKeyAlgorithm()
  • getAuthenticatorData()

There's also getTransports().

https://w3c.github.io/webauthn/#iface-authenticatorattestationresponse

We could:

  • Not expose these.
  • Expose the actual WebAuthn API response object so that the user can call anything they want on it. (We may want to expose our base64url conversion to help with this.)
  • Forward the available methods without modification.
  • Proxy any available methods, converting to baseurl64.
  • Always call these methods, and attach the results (we do this for getClientExtensionResults() already).

The latter is the most convenient, but it results in extra data. The simple use case for @github/webauthn-json is to send the results to the server, which still has to process the response from CBOR. These methods would not really be useful for this case.

However, there are cases where you might want to do some or all processing on the client side, where this could save code.

Add support for `appidExclude` extension

Hi again!

As title says, I think it might be a good idea to add the appidExclude extension since it was introduced in the spec some time ago (see w3c/webauthn#1244) and it also wasn't removed from the spec when unimplemented extensions were removed (see w3c/webauthn#1386) ๐Ÿ™‚

interface FullWebAuthnExtensionsJSON {
appid?: string;
txAuthSimple?: string;
txAuthGeneric?: {
contentType: string;
content: Base64urlString;
};
authnSel?: Base64urlString[];
exts?: boolean;
uvi?: boolean;
loc?: boolean;
uvm?: boolean;
authenticatorBiometricPerfBounds?: {
FAR: number;
FRR: number;
};
}

Write tests using Chrome's virtual authenticator API

I've held off on writing thorough tests, because getting a good mock WebAuthn authenticator working was a bit daunting. However, Chrome's DevTools protocol now supports virtual authenticators: https://chromedevtools.github.io/devtools-protocol/tot/WebAuthn/

This should make it possible to write fairly robust tests.

I haven't set up a GitHub action testing using the DevTools protocol, so we could use some help if anyone is familiar with how to set that up.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.