🔐
@artifact-project/webauthn A set of tools for building an API and interacts with WebAuthn.
npm i --save @artifact-project/webauthn
Features
- Easy and Flexibility API
🧬 - Supported IFrames (regardless of nesting) 💪🏻
- Runtime logger & verbose mode
✴️ - Fully testelably
✅
Using in iframe
In parent window
import { allowFrom } from '@artifact-project/webauthn/allow';
allowFrom(['mail.ru', '{o2,account}.mail.ru']);
Or embed the code in the parent window
<html>
<head>
<script>
/* Replace this comment on the code from this file: ./node_modules/@artifact-project/webauthn/allow.js */
webauthn.allowFrom(['mail.ru', '{o2,account}.mail.ru']);
</script>
</head>
<body>...</body>
</html>
Inside iframe
import { allowFor } from '@artifact-project/webauthn';
allowFor(['mail.ru', '*.mail.ru']);
Credential Create Request (aka Registration)
import {
credentials,
createMultiPhaseRequest,
fetchJSON,
parseAsCredentialCreationOptionsAndExtra,
encodeAttestationResponsePayload,
} from '@artifact-project/webauthn';
const credentialCreateRequest = createMultiPhaseRequest<{login: params}>()
.phase((params) => fetchJSON('/api/v1/webauthn/credentials/create', params)
.then(res => res.body)
.then(parseAsCredentialCreationOptionsAndExtra)
)
.phase(({options, extra}) => credentials.create(options).then(credential => ({
extra,
options,
credential,
})))
.phase(
({extra, credential, options}) => fetchJSON('/api/v1/webauthn/credentials/create/confirm', {
...extra,
attestation: encodeAttestationResponsePayload(credential),
}).then(res => ({
extra: res.body,
options,
credential,
}))
)
;
credentialCreateRequest({
login: 'ibn@rubaxa.org',
}).then(console.log);
// {
// extra: {id: "...", login: "ibn@rubaxa.org"},
// options: {...},
// credential: {...},
// }
Credential Request (aka Login)
import {
credentials,
createMultiPhaseRequest,
fetchJSON,
parseAsCredentialRequestOptionsAndExtra,
encodeAssertionResponsePlayload,
} from '@artifact-project/webauthn';
const credentialRequest = createMultiPhaseRequest<{login: params}>()
.phase((params) => fetchJSON('/api/v1/webauthn/credentials/get', params)
.then(res => res.body)
.then(parseAsCredentialRequestOptionsAndExtra)
)
.phase(({options, extra}) => credentials.get(options).then(credential => ({
extra,
options,
credential,
})))
.phase(
({extra, credential, options}) => fetchJSON('/api/v1/webauthn/credentials/get/confirm', {
...extra,
assertion: encodeAssertionResponsePlayload(credential),
}).then(res => ({
extra: res.body,
options,
credential,
}))
)
;
credentialRequest({
login: 'ibn@rubaxa.org',
}).then(console.log);
// {
// extra: {token: "...", url: "...", expires: 123},
// options: {...},
// credential: {...},
// }
API
-
isCredentialsSupported():
boolean
-
getLogEntries():
Array<{msg: string; detail: object;}>
-
credentials
-
create(options?:
CredentialCreationOptions
):Promise<Credential | null>
-
get(options?:
CredentialRequestOptions
):Promise<Credential | null>
-
create(options?:
-
createPhaseRequest
<P extends object>
():(params: P) => Promise<R>
-
fetchJSON(url:
string
, params:object
):Response
-
Decode
-
decodeBuffer(value:
string
):ArrayBuffer
-
decodePublicKeyCredentialCreationOptions(value:
object
):PublicKeyCredentialCreationOptions
-
decodePublicKeyCredentialRequestOptions(value:
object
):PublicKeyCredentialRequestOptions
-
decodeCredentialCreationOptions(value:
object
):CredentialCreationOptions
-
decodeCredentialRequestOptions(value:
object
):CredentialRequestOptions
-
decodeAttestationResponsePayload(credential:
object
):PublicKeyCredentialWithAttestationResponse
-
decodeAssertionResponsePlayload(credential:
object
):PublicKeyCredentialWithAssertionResponse
-
decodeBuffer(value:
-
Encode
-
encodeBuffer(buffer:
ArrayBuffer
):string
-
encodeAttestationResponsePayload(credential:
PublicKeyCredential
):EncodedPublicKeyCredential
-
encodeAssertionResponsePlayload(credential:
PublicKeyCredential
):EncodedPublicKeyCredential
-
encodeBuffer(buffer:
Development
npm i
-
npm test
, code coverage