@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>
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);
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);
API
- isCredentialsSupported():
boolean
- getLogEntries():
Array<{msg: string; detail: object;}>
- credentials
- create(options?:
CredentialCreationOptions
): Promise<Credential | null>
- get(options?:
CredentialRequestOptions
): Promise<Credential | null>
- 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
- Encode
- encodeBuffer(buffer:
ArrayBuffer
): string
- encodeAttestationResponsePayload(credential:
PublicKeyCredential
): EncodedPublicKeyCredential
- encodeAssertionResponsePlayload(credential:
PublicKeyCredential
): EncodedPublicKeyCredential
Development