@adyen/bpscaweb
Advanced tools
Comparing version 0.0.2 to 0.1.0
@@ -1,7 +0,1 @@ | ||
class ServerError extends Error { | ||
constructor(errorResponse, ...params) { | ||
super(...params); | ||
this.errorResponse = errorResponse; | ||
} | ||
} | ||
var base64Js = {}; | ||
@@ -102,3 +96,3 @@ base64Js.byteLength = byteLength; | ||
const removeEmptyJsonElements = (obj) => { | ||
Object.keys(obj).forEach(function(key) { | ||
Object.keys(obj).forEach((key) => { | ||
obj[key] && typeof obj[key] === "object" && removeEmptyJsonElements(obj[key]) || (obj[key] === "" || obj[key] === null) && delete obj[key]; | ||
@@ -109,7 +103,7 @@ }); | ||
const getBaseUrl = () => { | ||
const pathArray = window.location.href.split("/"); | ||
const protocol = pathArray[0]; | ||
const host = pathArray[2]; | ||
const baseUrl = protocol + "//" + host; | ||
return baseUrl; | ||
const { | ||
host, | ||
protocol | ||
} = new URL(window.location.href); | ||
return `${protocol}//${host}`; | ||
}; | ||
@@ -122,7 +116,7 @@ const getHostName = () => { | ||
}; | ||
const base64urlToUint8array = (base64Bytes) => { | ||
const base64ToUint8array = (base64Bytes) => { | ||
const padding = "====".substring(0, (4 - base64Bytes.length % 4) % 4); | ||
return base64Js.toByteArray((base64Bytes + padding).replace(/\//g, "_").replace(/\+/g, "-")); | ||
return base64Js.toByteArray(base64Bytes + padding); | ||
}; | ||
const uint8arrayToBase64url = (bytes) => { | ||
const uint8arrayToBase64 = (bytes) => { | ||
if (!bytes) { | ||
@@ -132,328 +126,131 @@ return ""; | ||
if (bytes instanceof Uint8Array) { | ||
return base64Js.fromByteArray(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); | ||
return base64Js.fromByteArray(bytes); | ||
} | ||
return uint8arrayToBase64url(new Uint8Array(bytes)); | ||
return uint8arrayToBase64(new Uint8Array(bytes)); | ||
}; | ||
function createCredential(registrationInitiationResponse) { | ||
const formattedPublicKey = { | ||
const authenticateWithCredential = (publicKeyCredentialRequestOptions) => { | ||
var _a; | ||
const credentialGetOptions = { | ||
publicKey: { | ||
...registrationInitiationResponse.publicKeyCredentialCreationOptions, | ||
challenge: base64urlToUint8array(registrationInitiationResponse.publicKeyCredentialCreationOptions.challenge), | ||
user: { | ||
...registrationInitiationResponse.publicKeyCredentialCreationOptions.user, | ||
id: base64urlToUint8array(registrationInitiationResponse.publicKeyCredentialCreationOptions.user.id) | ||
} | ||
...publicKeyCredentialRequestOptions, | ||
challenge: base64ToUint8array(publicKeyCredentialRequestOptions.challenge) | ||
} | ||
}; | ||
return navigator.credentials.create(formattedPublicKey); | ||
} | ||
function buildRegistrationInitiationRequest({ | ||
deviceName, | ||
originUrl, | ||
relyingPartyId, | ||
relyingPartyName, | ||
correlation | ||
}) { | ||
const registrationInitiationRequest = { | ||
device: { | ||
name: deviceName, | ||
type: "browser" | ||
}, | ||
origin: { | ||
url: originUrl, | ||
platform: "web" | ||
}, | ||
correlation: { | ||
id: correlation.correlationId, | ||
type: correlation.correlationType, | ||
state: "state2" | ||
}, | ||
rp: { | ||
id: relyingPartyId, | ||
name: relyingPartyName | ||
} | ||
}; | ||
const registrationInitiationRequestWrapped = { | ||
correlationId: correlation.correlationId, | ||
strongCustomerAuthentication: { | ||
sdkOutput: btoa(JSON.stringify(registrationInitiationRequest)) | ||
} | ||
}; | ||
return registrationInitiationRequestWrapped; | ||
} | ||
async function requestDevice(startRegisterDeviceUrl, data, headerOptions) { | ||
const response = await fetch(startRegisterDeviceUrl, { | ||
method: "POST", | ||
headers: { | ||
...headerOptions, | ||
"Content-Type": "application/json" | ||
}, | ||
body: JSON.stringify(data) | ||
// body data type must match "Content-Type" header | ||
}); | ||
return response; | ||
} | ||
function initiateRegistration(request) { | ||
const registrationInitiationRequestWrapped = buildRegistrationInitiationRequest(request); | ||
const { | ||
configuration | ||
} = request; | ||
return requestDevice(configuration.startRegisterDeviceUrl, registrationInitiationRequestWrapped, configuration.globalHeaders).then((response) => { | ||
if (response.ok) { | ||
return response.json(); | ||
} | ||
return response.json().then((response2) => { | ||
throw new ServerError(response2, "Error occurred during registration initiation stage"); | ||
}); | ||
}); | ||
} | ||
function buildRegistrationFinalisationRequest({ | ||
deviceReference, | ||
publicKeyCredential, | ||
relyingPartyId, | ||
relyingPartyName, | ||
originUrl, | ||
correlation | ||
}) { | ||
const registerResponse = publicKeyCredential.response; | ||
const formattedPublicKeyCredential = { | ||
if ((_a = credentialGetOptions.publicKey) == null ? void 0 : _a.allowCredentials) { | ||
credentialGetOptions.publicKey.allowCredentials = credentialGetOptions.publicKey.allowCredentials.map((cred) => ({ | ||
...cred, | ||
id: base64ToUint8array(cred.id) | ||
})); | ||
} | ||
return navigator.credentials.get(credentialGetOptions); | ||
}; | ||
function createFormattedPublicKeyCredential(publicKeyCredential) { | ||
const credentialResponse = publicKeyCredential.response; | ||
return { | ||
type: publicKeyCredential.type, | ||
id: publicKeyCredential.id, | ||
type: publicKeyCredential.type, | ||
rp: { | ||
id: relyingPartyId, | ||
name: relyingPartyName | ||
}, | ||
rawId: uint8arrayToBase64(publicKeyCredential.rawId), | ||
response: { | ||
attestationObject: uint8arrayToBase64url(registerResponse.attestationObject), | ||
clientDataJSON: uint8arrayToBase64url(registerResponse.clientDataJSON), | ||
transports: registerResponse.getTransports() || [] | ||
authenticatorData: uint8arrayToBase64(credentialResponse.authenticatorData), | ||
clientDataJSON: uint8arrayToBase64(credentialResponse.clientDataJSON), | ||
signature: uint8arrayToBase64(credentialResponse.signature), | ||
userHandle: uint8arrayToBase64(credentialResponse.userHandle) | ||
} | ||
}; | ||
const registrationFinalisationRequest = { | ||
publicKeyCredential: formattedPublicKeyCredential, | ||
device: { | ||
type: "browser" | ||
}, | ||
origin: { | ||
url: originUrl, | ||
platform: "web" | ||
}, | ||
correlation: { | ||
id: correlation.correlationId, | ||
type: correlation.correlationType, | ||
state: "state2" | ||
} | ||
}; | ||
const registrationFinalisationRequestWrapped = { | ||
correlationId: correlation.correlationId, | ||
strongCustomerAuthentication: { | ||
sdkOutput: btoa(JSON.stringify(registrationFinalisationRequest)) | ||
}, | ||
id: deviceReference | ||
}; | ||
return registrationFinalisationRequestWrapped; | ||
} | ||
async function confirmDevice(finishRegisterDeviceUrl, data, headerOptions) { | ||
const response = await fetch(finishRegisterDeviceUrl, { | ||
method: "POST", | ||
headers: { | ||
...headerOptions, | ||
"Content-Type": "application/json" | ||
}, | ||
body: JSON.stringify(data) | ||
// body data type must match "Content-Type" header | ||
function authenticate(sdkInput) { | ||
const unwrappedResponseJsonStr = atob(sdkInput); | ||
const json = removeEmptyJsonElements(JSON.parse(unwrappedResponseJsonStr)); | ||
return authenticateWithCredential(json.publicKeyCredentialRequestOptions).then((credential) => { | ||
const publicKeyCredential = credential; | ||
const authenticationRequest = { | ||
device: "browser", | ||
origin: getBaseUrl(), | ||
rp: { | ||
id: getHostName() | ||
}, | ||
traceparent: json.traceparent, | ||
publicKeyCredential: createFormattedPublicKeyCredential(publicKeyCredential) | ||
}; | ||
return btoa(JSON.stringify(authenticationRequest)); | ||
}); | ||
return response; | ||
} | ||
function finaliseRegistration(request) { | ||
const registrationFinalisationRequestWrapped = buildRegistrationFinalisationRequest(request); | ||
const { | ||
configuration | ||
} = request; | ||
return confirmDevice(configuration.finishRegisterDeviceUrl, registrationFinalisationRequestWrapped, configuration.globalHeaders).then((response) => { | ||
if (response.ok) { | ||
return response; | ||
} | ||
return response.json().then((response2) => { | ||
throw new ServerError(response2, "Error occurred during registration finalisation stage"); | ||
}); | ||
}); | ||
class SCAUnavailableError extends Error { | ||
constructor(message) { | ||
super(message); | ||
this.code = "SCA_UNAVAILABLE"; | ||
} | ||
} | ||
function registerDevice(request) { | ||
let deviceReference = void 0; | ||
const originUrl = getBaseUrl(); | ||
const relyingPartyId = getHostName(); | ||
return initiateRegistration({ | ||
...request, | ||
originUrl, | ||
relyingPartyId | ||
}).then((registrationInitiationResponse) => { | ||
deviceReference = registrationInitiationResponse.id; | ||
const unwrappedResponseJsonStr = atob(registrationInitiationResponse.sdkInput); | ||
return removeEmptyJsonElements(JSON.parse(unwrappedResponseJsonStr)); | ||
}).then((registrationInitiationResponse) => { | ||
return createCredential(registrationInitiationResponse); | ||
}).then((publicKeyCredential) => ({ | ||
publicKeyCredential, | ||
relyingPartyId, | ||
relyingPartyName: request.relyingPartyName, | ||
originUrl, | ||
correlation: request.correlation, | ||
deviceReference, | ||
configuration: request.configuration | ||
})).then((finishRequest) => { | ||
return finaliseRegistration(finishRequest); | ||
}).catch((ex) => { | ||
console.error("Error performing registration: " + ex); | ||
throw ex; | ||
}); | ||
} | ||
const WWW_AUTHENTICATE_HEADER_KEY = "WWW-Authenticate"; | ||
const AUTH_PARAM_HEADER_KEY = "auth-param1"; | ||
const SCA_REALM_HEADER_KEY = "SCA realm"; | ||
const HTTP_UNAUTHORISED = 401; | ||
function isHttp2xxStatus(status) { | ||
return status == 200 || status == 201 || status == 202 || status == 203 || status == 204; | ||
} | ||
function executeAuthenticatedHttpRequest(privilegedRequest, wwwAuthenticateHeader) { | ||
return fetch(privilegedRequest.url, { | ||
headers: { | ||
...privilegedRequest.headers, | ||
[WWW_AUTHENTICATE_HEADER_KEY]: wwwAuthenticateHeader | ||
}, | ||
method: privilegedRequest.operation, | ||
body: privilegedRequest.body | ||
}); | ||
} | ||
function extractAuthParam1(wwwAuthenticateHeader) { | ||
if (!wwwAuthenticateHeader || wwwAuthenticateHeader.indexOf(AUTH_PARAM_HEADER_KEY) == -1) { | ||
throw new Error(`Incorrect format for ${WWW_AUTHENTICATE_HEADER_KEY} header, expected ${AUTH_PARAM_HEADER_KEY} key`); | ||
} | ||
var parts = wwwAuthenticateHeader.split(" "); | ||
var authParam1Value = void 0; | ||
for (var i = 0; i < parts.length; i++) { | ||
if (parts[i].startsWith(AUTH_PARAM_HEADER_KEY)) { | ||
if (parts[i].length > AUTH_PARAM_HEADER_KEY.length) { | ||
authParam1Value = parts[i].substring(AUTH_PARAM_HEADER_KEY.length + 1); | ||
function checkAvailability(configuration) { | ||
if (window.PublicKeyCredential) { | ||
return PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().then((available) => { | ||
if (available) { | ||
const originUrl = getBaseUrl(); | ||
const relyingPartyId = getHostName(); | ||
const relyingPartyName = configuration.relyingPartyName; | ||
const sdkOutput = { | ||
device: "browser", | ||
origin: originUrl, | ||
rp: { | ||
id: relyingPartyId, | ||
name: relyingPartyName | ||
} | ||
}; | ||
return btoa(JSON.stringify(sdkOutput)); | ||
} else { | ||
throw new SCAUnavailableError("No platform authenticator available"); | ||
} | ||
} | ||
}); | ||
} else { | ||
throw new SCAUnavailableError("No PublicKeyCredential available"); | ||
} | ||
if (!authParam1Value) { | ||
throw new Error(`Incorrect format for ${WWW_AUTHENTICATE_HEADER_KEY} header, malformed ${AUTH_PARAM_HEADER_KEY}`); | ||
} | ||
return JSON.parse(atob(authParam1Value)); | ||
} | ||
async function initiationAuthentication(privilegedRequest, device) { | ||
const authenticationInitiationRequest = { | ||
device: { | ||
type: "browser" | ||
}, | ||
origin: { | ||
url: device.originUrl | ||
}, | ||
rp: { | ||
id: device.relyingPartyId | ||
}, | ||
correlation: { | ||
type: device.correlationType | ||
} | ||
}; | ||
const encodedAuthenticationInitiationRequest = btoa(JSON.stringify(authenticationInitiationRequest)); | ||
const wwwAuthenticateHeader = `${SCA_REALM_HEADER_KEY}="${privilegedRequest.scaRealm}" ${AUTH_PARAM_HEADER_KEY}=${encodedAuthenticationInitiationRequest}`; | ||
return executeAuthenticatedHttpRequest(privilegedRequest, wwwAuthenticateHeader).then(async (response) => { | ||
if (isHttp2xxStatus(response.status)) { | ||
const responseBody = await response.text(); | ||
const privilegedRequestResponse = responseBody && responseBody.length > 0 ? JSON.parse(responseBody) : {}; | ||
const authenticationExempt = { | ||
response: privilegedRequestResponse | ||
}; | ||
console.log("Received HTTP 2xx status on authentication initiation, not proceeding with authentication"); | ||
return Promise.reject(authenticationExempt); | ||
} | ||
if (response.status == HTTP_UNAUTHORISED) { | ||
let authenticationInitiationResponse = extractAuthParam1(response.headers.get(WWW_AUTHENTICATE_HEADER_KEY)); | ||
authenticationInitiationResponse = removeEmptyJsonElements(authenticationInitiationResponse); | ||
return { | ||
response: authenticationInitiationResponse | ||
}; | ||
} | ||
return response.json().then((response2) => { | ||
throw new ServerError(response2, "Error occurred during authentication initiation stage"); | ||
}); | ||
}).then((authenticationInitiationResponse) => { | ||
return authenticationInitiationResponse; | ||
}); | ||
} | ||
function authenticateWithCredential(authenticationInitiationResponse) { | ||
const credentialGetOptions = { | ||
const PUBLIC_KEY_ALGORITHMS = [-7, -8, -257]; | ||
function createCredential(registrationInitiationResponse) { | ||
const formattedPublicKey = { | ||
publicKey: { | ||
...authenticationInitiationResponse.response.publicKeyCredentialRequestOptions, | ||
challenge: base64urlToUint8array(authenticationInitiationResponse.response.publicKeyCredentialRequestOptions.challenge) | ||
...registrationInitiationResponse.publicKeyCredentialCreationOptions, | ||
challenge: base64ToUint8array(registrationInitiationResponse.publicKeyCredentialCreationOptions.challenge), | ||
user: { | ||
...registrationInitiationResponse.publicKeyCredentialCreationOptions.user, | ||
id: base64ToUint8array(registrationInitiationResponse.publicKeyCredentialCreationOptions.user.id) | ||
} | ||
} | ||
}; | ||
for (let i = 0; i < credentialGetOptions.publicKey.allowCredentials.length; i++) { | ||
credentialGetOptions.publicKey.allowCredentials[i].id = base64urlToUint8array(credentialGetOptions.publicKey.allowCredentials[i].id); | ||
if (formattedPublicKey.publicKey) { | ||
formattedPublicKey.publicKey.pubKeyCredParams = formattedPublicKey.publicKey.pubKeyCredParams.filter((param) => PUBLIC_KEY_ALGORITHMS.includes(param.alg)); | ||
} | ||
return navigator.credentials.get(credentialGetOptions); | ||
return navigator.credentials.create(formattedPublicKey); | ||
} | ||
function buildAuthenticationFinalisationRequest(publicKeyCredential, device) { | ||
const credentialResponse = publicKeyCredential.response; | ||
const formattedPublicKeyCredential = { | ||
type: publicKeyCredential.type, | ||
id: publicKeyCredential.id, | ||
rawId: uint8arrayToBase64url(publicKeyCredential.rawId), | ||
response: { | ||
authenticatorData: uint8arrayToBase64url(credentialResponse.authenticatorData), | ||
clientDataJSON: uint8arrayToBase64url(credentialResponse.clientDataJSON), | ||
signature: uint8arrayToBase64url(credentialResponse.signature), | ||
userHandle: uint8arrayToBase64url(credentialResponse.userHandle) | ||
} | ||
}; | ||
const authenticationFinalisationRequest = { | ||
device: { | ||
type: "browser" | ||
}, | ||
origin: { | ||
url: device.originUrl | ||
}, | ||
rp: { | ||
id: device.relyingPartyId | ||
}, | ||
correlation: { | ||
type: device.correlationType | ||
}, | ||
publicKeyCredential: formattedPublicKeyCredential | ||
}; | ||
return authenticationFinalisationRequest; | ||
} | ||
async function finaliseAuthentication(privilegedRequest, publicKeyCredential, device) { | ||
const authenticationFinalisationRequest = buildAuthenticationFinalisationRequest(publicKeyCredential, device); | ||
const authParam1 = btoa(JSON.stringify(authenticationFinalisationRequest)); | ||
const wwwAuthenticateHeader = `${SCA_REALM_HEADER_KEY}="${privilegedRequest.scaRealm}" ${AUTH_PARAM_HEADER_KEY}=${authParam1}`; | ||
return executeAuthenticatedHttpRequest(privilegedRequest, wwwAuthenticateHeader).then(async (privilegedResponse) => { | ||
if (privilegedResponse.ok) { | ||
const responseBody = await privilegedResponse.text(); | ||
const privilegedRequestResponse = responseBody && responseBody.length > 0 ? JSON.parse(responseBody) : {}; | ||
return privilegedRequestResponse; | ||
} | ||
return privilegedResponse.json().then((authenticationFinalisationResponse) => { | ||
throw new ServerError(authenticationFinalisationResponse, "Error occurred during authentication finalisation stage"); | ||
}); | ||
}); | ||
} | ||
async function performAuthenticatedRequest(privilegedRequest) { | ||
const device = { | ||
originUrl: getBaseUrl(), | ||
function register(sdkInput, configuration) { | ||
const unwrappedResponseJsonStr = atob(sdkInput); | ||
const json = removeEmptyJsonElements(JSON.parse(unwrappedResponseJsonStr)); | ||
return createCredential(json).then((publicKeyCredential) => ({ | ||
publicKeyCredential, | ||
relyingPartyId: getHostName(), | ||
correlationType: privilegedRequest.correlationType | ||
}; | ||
return initiationAuthentication(privilegedRequest, device).then((authenticationInitiationResponse) => { | ||
return authenticationInitiationResponse; | ||
}).then((authenticationInitiationResponse) => { | ||
return authenticateWithCredential(authenticationInitiationResponse); | ||
}).then((publicKeyCredential) => { | ||
return finaliseAuthentication(privilegedRequest, publicKeyCredential, device); | ||
}).catch((ex) => { | ||
console.error("Error performing authentication: " + ex); | ||
throw ex; | ||
relyingPartyName: configuration.relyingPartyName, | ||
originUrl: getBaseUrl() | ||
})).then((request) => { | ||
const publicKeyCredential = request.publicKeyCredential; | ||
const registerResponse = publicKeyCredential.response; | ||
const formattedPublicKeyCredential = { | ||
id: uint8arrayToBase64(publicKeyCredential.rawId), | ||
type: publicKeyCredential.type, | ||
rp: { | ||
id: request.relyingPartyId, | ||
name: request.relyingPartyName | ||
}, | ||
response: { | ||
attestationObject: uint8arrayToBase64(registerResponse.attestationObject), | ||
clientDataJSON: uint8arrayToBase64(registerResponse.clientDataJSON), | ||
transports: registerResponse.getTransports() || [] | ||
} | ||
}; | ||
const sdkOutput = { | ||
publicKeyCredential: formattedPublicKeyCredential, | ||
device: "browser", | ||
origin: request.originUrl, | ||
traceparent: json.traceparent | ||
}; | ||
return btoa(JSON.stringify(sdkOutput)); | ||
}); | ||
@@ -468,16 +265,11 @@ } | ||
} | ||
registerDevice(request) { | ||
request.configuration = { | ||
...this.configuration, | ||
...request.configuration | ||
}; | ||
return registerDevice(request); | ||
checkAvailability() { | ||
return checkAvailability(this.configuration); | ||
} | ||
authorize(request) { | ||
request.headers = { | ||
...this.configuration.globalHeaders, | ||
...request.headers | ||
}; | ||
return performAuthenticatedRequest(request); | ||
register(sdkInput) { | ||
return register(sdkInput, this.configuration); | ||
} | ||
authenticate(sdkInput) { | ||
return authenticate(sdkInput); | ||
} | ||
} | ||
@@ -484,0 +276,0 @@ export { |
@@ -1,2 +0,1 @@ | ||
import { PrivilegedRequest } from './types'; | ||
export declare function performAuthenticatedRequest(privilegedRequest: PrivilegedRequest): Promise<any>; | ||
export declare function authenticate(sdkInput: string): Promise<String>; |
@@ -1,5 +0,1 @@ | ||
export declare const WWW_AUTHENTICATE_HEADER_KEY = "WWW-Authenticate"; | ||
export declare const AUTH_PARAM_HEADER_KEY = "auth-param1"; | ||
export declare const SCA_REALM_HEADER_KEY = "SCA realm"; | ||
export declare const HTTP_OK = 200; | ||
export declare const HTTP_UNAUTHORISED = 401; | ||
export declare const PUBLIC_KEY_ALGORITHMS: number[]; |
@@ -1,2 +0,2 @@ | ||
import { RegistrationDeviceRequest } from './types'; | ||
export declare function registerDevice(request: RegistrationDeviceRequest): Promise<Response>; | ||
import { ScaConfiguration } from './types'; | ||
export declare function register(sdkInput: string, configuration: ScaConfiguration): Promise<String>; |
@@ -1,2 +0,2 @@ | ||
import { ScaConfiguration, RegistrationDeviceRequest, PrivilegedRequest } from './types'; | ||
import { ScaConfiguration } from './types'; | ||
export declare class ScaWebauthn { | ||
@@ -6,4 +6,5 @@ private readonly configuration; | ||
static create(configuration: ScaConfiguration): ScaWebauthn; | ||
registerDevice(request: RegistrationDeviceRequest): Promise<Response>; | ||
authorize(request: PrivilegedRequest): Promise<any>; | ||
checkAvailability(): Promise<String>; | ||
register(sdkInput: string): Promise<String>; | ||
authenticate(sdkInput: string): Promise<String>; | ||
} |
@@ -1,49 +0,7 @@ | ||
export type scaProperties = { | ||
deviceName: string; | ||
partyName: string; | ||
}; | ||
export type ScaConfiguration = { | ||
startRegisterDeviceUrl: string; | ||
finishRegisterDeviceUrl: string; | ||
globalHeaders?: any; | ||
relyingPartyName: string; | ||
}; | ||
export declare enum CorrelationTypes { | ||
paymentInstrument = "payment_instrument" | ||
export declare class SCAUnavailableError extends Error { | ||
code: string; | ||
constructor(message: string); | ||
} | ||
type Correlation = { | ||
correlationId: string; | ||
correlationType: CorrelationTypes; | ||
}; | ||
export interface RegistrationDeviceRequest { | ||
relyingPartyName: string; | ||
deviceName: string; | ||
correlation: Correlation; | ||
configuration: ScaConfiguration; | ||
} | ||
interface RegistrationDeviceParameters { | ||
relyingPartyId: string; | ||
originUrl: string; | ||
relyingPartyName: string; | ||
correlation: Correlation; | ||
configuration: ScaConfiguration; | ||
} | ||
export interface StartRegistrationDeviceParameters extends RegistrationDeviceParameters { | ||
deviceName: string; | ||
} | ||
export interface FinishRegistrationDeviceParameters extends RegistrationDeviceParameters { | ||
deviceReference: string; | ||
publicKeyCredential: PublicKeyCredential; | ||
} | ||
export interface PrivilegedRequest { | ||
scaRealm: string; | ||
url: string; | ||
operation: string; | ||
body: BodyInit; | ||
headers: any; | ||
correlationType: CorrelationTypes; | ||
} | ||
export declare class ServerError extends Error { | ||
errorResponse: any; | ||
constructor(errorResponse: any, ...params: any[]); | ||
} | ||
export {}; |
export declare const removeEmptyJsonElements: (obj: any) => any; | ||
export declare const getBaseUrl: () => string; | ||
export declare const getHostName: () => string; | ||
export declare const base64urlToUint8array: (base64Bytes: any) => Uint8Array; | ||
export declare const uint8arrayToBase64url: (bytes: ArrayBuffer | Uint8Array | null) => string; | ||
export declare const base64ToUint8array: (base64Bytes: any) => Uint8Array; | ||
export declare const uint8arrayToBase64: (bytes: ArrayBuffer | Uint8Array | null) => string; |
{ | ||
"name": "@adyen/bpscaweb", | ||
"version": "0.0.2", | ||
"version": "0.1.0", | ||
"description": "Balance Platform SCA Web library", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -1,1 +0,71 @@ | ||
# bpscaweb | ||
# Balance Platform SCA Web | ||
This library offers an easy way to perform operations with **Strong Customer Authorization**. This library is based on [**WebAuthn**](https://www.w3.org/TR/webauthn/) to guarantee the security of the operations. | ||
## Installation | ||
You can use this library direclty on your browser or you can add as a dependency on your `JS` project. | ||
With **npm** do | ||
```bash | ||
npm install @adyen/bpscaweb | ||
``` | ||
With **browsers** do | ||
```html | ||
<script type="module" src="bpscaweb.es.js"></script> | ||
<script type="module"> | ||
import ScaWebauthn from '/js/bpscaweb.es.js'; | ||
... | ||
</script> | ||
``` | ||
## Configuration | ||
Once you have installed the component, you can configure it when you create a new _handler_. | ||
```js | ||
const handler = ScaWebauthn.create(options); | ||
``` | ||
### Options | ||
These are the options you can pass to the component | ||
| Option | Required | Type | Description | | ||
| :---------------: | :--------------------------: | :--------------------------: | :---------------------------------------------- | | ||
| relyingPartyName | Yes | string | Your identifier for the device to be registered | | ||
**Example**: Create a handler | ||
```javascript | ||
const scaWebauthn = ScaWebauthn.create({ | ||
relyingPartyName: 'adyen_bpsca', | ||
}); | ||
``` | ||
## Check availability | ||
Check if SCA is available on the device. | ||
```javascript | ||
const sdkOutput = await scaWebauthn.checkAvailability(); | ||
```` | ||
## Register device | ||
Exchange the `sdkInput` return by the backend in the initiate register call | ||
```javascript | ||
const sdkOutput = await scaWebauthn.register(sdkInput); // the new output that will be shared with the server to complete the registration | ||
```` | ||
## Authenticate device | ||
Exchange the `sdkInput` return by the backend in the first call | ||
```javascript | ||
const sdkOutput = await scaWebauthn.authenticate(sdkInput); // the new output that will be shared with the server to authenticate the call | ||
```` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
4153169
26
27107
72
1