Skip to content

Commit

Permalink
Initial implementation (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
tjconcept authored Oct 20, 2024
1 parent c1d49fc commit 591c2a3
Show file tree
Hide file tree
Showing 5 changed files with 1,015 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
on: push
jobs:
tests:
timeout-minutes: 5
runs-on: ubuntu-latest
env:
DENO_DIR: deno_dependency_cache
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Deno (v2)
uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- name: Cache Deno dependencies
uses: actions/cache@v4
with:
path: ${{ env.DENO_DIR }}
key: cache_key_v1
- name: Run tests
run: deno --allow-env --allow-read test.js
24 changes: 24 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
semi: false
singleQuote: true
useTabs: true
bracketSpacing: false
tabWidth: 4
overrides:
- files:
- "*.md"
options:
proseWrap: always
useTabs: false
tabWidth: 2
- files:
- "*.prettierrc"
options:
useTabs: false
tabWidth: 2
singleQuote: false
- files:
- "*.yml"
options:
useTabs: false
tabWidth: 2
singleQuote: false
169 changes: 169 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import {
encodeBase64Url,
decodeBase64Url,
} from 'https://esm.sh/jsr/@std/[email protected]/base64url.js'
import {concat} from 'https://esm.sh/jsr/@std/[email protected]/concat.js'

export const pubKeyCredParams = [
{alg: -8, type: 'public-key'}, // EdDSA
{alg: -7, type: 'public-key'}, // ES256
{alg: -257, type: 'public-key'}, // RS256
]

export function creationOptionsToJSON(options) {
// Partner function of PublicKeyCredential.parseCreationOptionsFromJSON(json)
return {
authenticatorSelection: {
residentKey: options.authenticatorSelection?.residentKey,
},
challenge:
options.challenge === undefined
? undefined
: encodeBase64Url(options.challenge),
pubKeyCredParams: options.pubKeyCredParams,
rp: options.rp,
user: {
name: options.user?.name,
displayName: options.user?.displayName,
id:
options.user?.id === undefined
? undefined
: encodeBase64Url(options.user.id),
},
}
}

export function parseCreationOptionsFromJSON(json) {
// Ponyfill of PublicKeyCredential.parseCreationOptionsFromJSON(json)
return {
authenticatorSelection: {
residentKey: json.authenticatorSelection?.residentKey,
},
challenge:
json.challenge === undefined
? undefined
: decodeBase64Url(json.challenge),
pubKeyCredParams: json.pubKeyCredParams,
rp: json.rp,
user: {
name: json.user?.name,
displayName: json.user?.displayName,
id:
json.user?.id === undefined
? undefined
: decodeBase64Url(json.user.id),
},
}
}

export function requestOptionsToJSON(options) {
// Partner function of PublicKeyCredential.parseRequestOptionsFromJSON(json)
return {
allowCredentials: options.allowCredentials?.map((c) => ({
id: encodeBase64Url(c.id),
transports: c.transports,
type: c.type,
})),
challenge:
options.challenge === undefined
? undefined
: encodeBase64Url(options.challenge),
extensions: options.extensions,
hints: options.hints,
rpId: options.rpId,
timeout: options.timeout,
userVerification: options.userVerification,
}
}

export function parseRequestOptionsFromJSON(json) {
// Ponyfill of PublicKeyCredential.parseRequestOptionsFromJSON(json)
return {
allowCredentials: json.allowCredentials?.map((c) => ({
id: decodeBase64Url(c.id),
transports: c.transports,
type: c.type,
})),
challenge:
json.challenge === undefined
? undefined
: decodeBase64Url(json.challenge),
extensions: json.extensions,
hints: json.hints,
rpId: json.rpId,
timeout: json.timeout,
userVerification: json.userVerification,
}
}

export function assertionToJSON(credential) {
const r = credential.response
return {
id: credential.id,
rawId: encodeBase64Url(credential.rawId),
response: {
authenticatorData: encodeBase64Url(r.authenticatorData),
clientDataJSON: encodeBase64Url(r.clientDataJSON),
signature: encodeBase64Url(r.signature),
userHandle: encodeBase64Url(r.userHandle),
},
authenticatorAttachment: credential.authenticatorAttachment,
clientExtensionResults: {},
type: credential.type,
}
}

export function assertionFromJSON(json) {
const r = json.response
return {
id: json.id,
rawId: decodeBase64Url(json.rawId),
response: {
authenticatorData: decodeBase64Url(r.authenticatorData),
clientDataJSON: decodeBase64Url(r.clientDataJSON),
signature: decodeBase64Url(r.signature),
userHandle: decodeBase64Url(r.userHandle),
},
authenticatorAttachment: json.authenticatorAttachment,
clientExtensionResults: json.clientExtensionResults,
type: json.type,
}
}

export function attestationToJSON(credential) {
const r = credential.response
return {
id: credential.id,
rawId: encodeBase64Url(credential.rawId),
response: {
attestationObject: encodeBase64Url(r.attestationObject),
clientDataJSON: encodeBase64Url(r.clientDataJSON),
authenticatorData: encodeBase64Url(r.getAuthenticatorData()),
publicKey: encodeBase64Url(r.getPublicKey()),
publicKeyAlgorithm: r.getPublicKeyAlgorithm(),
transports: r.getTransports(),
},
authenticatorAttachment: credential.authenticatorAttachment,
clientExtensionResults: {},
type: credential.type,
}
}

export function attestationFromJSON(json) {
const r = json.response
return {
id: json.id,
rawId: decodeBase64Url(json.rawId),
response: {
attestationObject: decodeBase64Url(r.attestationObject),
clientDataJSON: decodeBase64Url(r.clientDataJSON),
authenticatorData: decodeBase64Url(r.authenticatorData),
publicKey: decodeBase64Url(r.publicKey),
publicKeyAlgorithm: r.publicKeyAlgorithm,
transports: r.transports,
},
authenticatorAttachment: json.authenticatorAttachment,
clientExtensionResults: json.clientExtensionResults,
type: json.type,
}
}
Loading

0 comments on commit 591c2a3

Please sign in to comment.