@yubion-dev-team/yubion-fido2-server-sdk-js
Version:
This project is an SDK to use YubiOn FIDO2 Server Service from Node.js.
392 lines • 20.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.YubiOnFssSdk = void 0;
const fss_sdk_config_1 = require("./fss-sdk-config");
const yup = __importStar(require("yup"));
const user_data_1 = require("./schema/user-data");
const credential_data_1 = require("./schema/credential-data");
const fss_api_requester_1 = require("./internal/fss-api-requester");
const schema_1 = require("./schema");
const fss_api_error_1 = require("./fss-api-error");
class YubiOnFssSdk {
config;
apiRequester;
/**
* Initializes a new instance of the YubiOnFssSdk class.
*
* @param {FssSdkConfigParameter} config - The configuration of the FIDO2 Server.
*/
constructor(config) {
this.config = (0, fss_sdk_config_1.convertConfig)(config);
this.apiRequester = (0, fss_api_requester_1.createApiRequester)(this.config);
}
getRpId() { return this.config.rpId; }
/**
* Gets a user by its ID.
*
* @param {string} userId - The ID of the user to get.
* @param {boolean} [withDisabledUser=false] - Whether to include disabled users in the result.
* @param {boolean} [withDisabledCredential=false] - Whether to include disabled credentials in the result.
*
* @returns {Promise<{ user: UserDataWithCredentialCount, credentials: Array<CredentialData> }>}
* A promise that resolves with an object containing the user and credential data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async getUser(userId, withDisabledUser = false, withDisabledCredential = false) {
return await this.apiRequester.request("getUser", { userId, withDisabledUser, withDisabledCredential }, {
schema: yup.object().shape({
user: user_data_1.UserDataWithCredentialCountSchema,
credentials: yup.array(credential_data_1.CredentialDataSchema),
signalCurrentUserDetailsOptions: schema_1.SignalCurrentUserDetailsOptionsSchema,
})
});
}
/**
* Retrieves all users.
*
* @param {boolean} [withDisabledUser=false] - Whether to include disabled users in the result.
*
* @returns {Promise<{ users: Array<UserDataWithCredentialCount> }>}
* A promise that resolves with an object containing an array of user data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async getAllUsers(withDisabledUser = false) {
return await this.apiRequester.request("getAllUsers", { withDisabledUser, }, {
schema: yup.object().shape({
users: yup.array(user_data_1.UserDataWithCredentialCountSchema),
})
});
}
/**
* Retrieves all users with the specified username.
*
* @param {string} userName - The username to search for.
* @param {boolean} [withDisabledUser=false] - Whether to include disabled users in the result.
*
* @returns {Promise<{ users: Array<UserDataWithCredentialCount> }>}
* A promise that resolves with an object containing an array of user data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async getUsersByUserName(userName, withDisabledUser = false) {
return await this.apiRequester.request("getUsersByUserName", { userName, withDisabledUser, }, {
schema: yup.object().shape({
users: yup.array(user_data_1.UserDataWithCredentialCountSchema),
})
});
}
/**
* Registers a new user.
*
* @param {UserDataRegisterParameter} user - The user data for registration.
*
* @returns {Promise<{ user: UserDataWithCredentialCount }>}
* A promise that resolves with an object containing the registered user data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async registerUser(user) {
return await this.apiRequester.request("registerUser", {
user,
}, {
schema: yup.object().shape({
user: user_data_1.UserDataWithCredentialCountSchema,
})
});
}
/**
* Updates the specified user.
*
* @param {UserDataUpdateParameter} user - The user data for update.
* @param {boolean} [withUpdatedCheck=false] - Whether to check for the updated date.
*
* @returns {Promise<{ user: UserDataWithCredentialCount, signalCurrentUserDetailsOptions : SignalCurrentUserDetailsOptions }>}
* A promise that resolves with an object containing the updated user data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async updateUser(user, withUpdatedCheck = false) {
return await this.apiRequester.request("updateUser", {
user,
options: {
withUpdatedCheck,
}
}, {
schema: yup.object().shape({
user: user_data_1.UserDataWithCredentialCountSchema,
signalCurrentUserDetailsOptions: schema_1.SignalCurrentUserDetailsOptionsSchema,
})
});
}
/**
* Deletes a user by its ID.
*
* @param {string} userId - The ID of the user to delete.
*
* @returns {Promise<{ user: UserDataWithCredentialCount }>}
* A promise that resolves with an object containing the deleted user data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async deleteUser(userId) {
return await this.apiRequester.request("deleteUser", { userId, }, {
schema: yup.object().shape({
user: user_data_1.UserDataWithCredentialCountSchema,
credentials: yup.array(credential_data_1.CredentialDataSchema),
signalAllAcceptedCredentialsOptions: schema_1.SignalAllAcceptedCredentialsOptionsSchema,
})
});
}
/**
* Starts a credential registration process.
*
* @param {Fido2StartRegisterParameter} startRegisterParameter - The request parameter for starting a credential registration.
*
* @returns {Promise<{ creationOptions: PublicKeyCredentialCreationOptionsJSON, user: UserDataWithCredentialCount, session: string }>}
* A promise that resolves with an object containing the creation options for the credential registration and the user data, and a session string.
* The session string is used to verify the credential registration in the {@link verifyRegisterCredential} method and to finish the credential registration in the {@link finishRegisterCredential} method.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async startRegisterCredential(startRegisterParameter) {
const result = await this.apiRequester.requestWithCookieResponse("registerCredential/start", startRegisterParameter, {
schema: yup.object().shape({
creationOptions: yup.object().shape({
attestation: yup.string().nullable(),
authenticatorSelection: yup.object().nullable().shape({
authenticatorAttachment: yup.string().nullable().oneOf(["platform", "cross-platform"]),
requireResidentKey: yup.boolean().nullable(),
residentKey: yup.string().nullable().oneOf(["discouraged", "preferred", "required"]),
userVerification: yup.string().nullable().oneOf(["discouraged", "preferred", "required"]),
}),
challenge: yup.string(),
excludeCredentials: yup.array(yup.object().shape({
id: yup.string(),
transports: yup.array(yup.string()).nullable(),
type: yup.string(),
})).nullable(),
extensions: yup.mixed().nullable(),
hints: yup.array(yup.string()).nullable(),
pubKeyCredParams: yup.array(yup.object().shape({
alg: yup.number(),
type: yup.string(),
})),
rp: yup.object().shape({
id: yup.string(),
name: yup.string(),
}),
timeout: yup.number().nullable(),
user: yup.object().shape({
id: yup.string(),
name: yup.string(),
displayName: yup.string().nullable(),
}),
}),
user: user_data_1.UserDataWithCredentialCountSchema,
})
});
if (!result.cookie) {
throw new fss_api_error_1.FssApiError("cookie not found.", { appStatus: "COMMUNICATION_FAILED" });
}
return {
...result.response,
session: result.cookie,
};
}
/**
* Verifies the credential registration parameters before the actual registration
* by analyzing the contents of the finishRegisterParameter. This method provides
* a clear and understandable format of the registration content for review.
* The return value should be checked by the RP (the program using the SDK) to
* determine if there are any issues. If no issues are found, the RP can proceed
* to call finishRegisterCredential. If there is no need to review the
* registration content, calling finishRegisterCredential directly is also acceptable.
*
* @param {Fido2FinishRegisterParameter} finishRegisterParameter - The parameters for finishing the credential registration.
* @param {string} session - The session string associated with the registration process.
*
* @returns {Promise<{ credential: CredentialData, user: UserDataWithCredentialCount }>}
* A promise that resolves with an object containing the credential data and user data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async verifyRegisterCredential(finishRegisterParameter, session) {
return await this.apiRequester.request("registerCredential/verify", finishRegisterParameter, {
schema: yup.object().shape({
credential: credential_data_1.CredentialDataSchema,
user: user_data_1.UserDataWithCredentialCountSchema,
}),
cookie: session,
});
}
/**
* Completes the credential registration process by verifying the credential
* registration information and saves the credential to the user account.
*
* @param {Fido2FinishRegisterParameter} finishRegisterParameter - The parameters for finishing the credential registration.
* @param {string} session - The session string associated with the registration process.
*
* @returns {Promise<{ credential: CredentialData, user: UserDataWithCredentialCount }>}
* A promise that resolves with an object containing the credential data and user data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async finishRegisterCredential(finishRegisterParameter, session) {
return await this.apiRequester.request("registerCredential/finish", finishRegisterParameter, {
schema: yup.object().shape({
credential: credential_data_1.CredentialDataSchema,
user: user_data_1.UserDataWithCredentialCountSchema,
}),
cookie: session,
});
}
/**
* Starts the authentication process with the specified user and parameters.
* If the user is not specified, the authentication is performed with discoverable credentials.
*
* @param {Fido2StartAuthenticateParameter} startAuthenticateParameter - The request parameter for starting an authentication.
*
* @returns {Promise<{ requestOptions: PublicKeyCredentialRequestOptionsJSON, user?: UserData, session: string }>}
* A promise that resolves with an object containing the request options for the authentication and the user data.
* If the user is not specified in the request parameter, the user data is null.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
* The session string is used to finish the authentication in the {@link finishAuthenticate} method.
*/
async startAuthenticate(startAuthenticateParameter) {
const result = await this.apiRequester.requestWithCookieResponse("authenticate/start", startAuthenticateParameter, {
schema: yup.object().shape({
requestOptions: yup.object().shape({
challenge: yup.string(),
allowCredentials: yup.array(yup.object().shape({
id: yup.string(),
transports: yup.array(yup.string()).nullable(),
type: yup.string(),
})).nullable(),
userVerification: yup.string().nullable().oneOf(["discouraged", "preferred", "required"]),
timeout: yup.number().nullable(),
hints: yup.array(yup.string()).nullable(),
extensions: yup.mixed().nullable(),
}),
user: user_data_1.UserDataWithCredentialCountSchema.nullable(),
})
});
if (!result.cookie) {
throw new fss_api_error_1.FssApiError("cookie not found.", { appStatus: "COMMUNICATION_FAILED" });
}
return {
...result.response,
session: result.cookie,
};
}
/**
* Finishes the authentication process by verifying the authentication information.
*
* @param {Fido2FinishAuthenticateParameter} finishAuthenticateParameter - The parameters for finishing the authentication.
* @param {string} session - The session string associated with the authentication process.
*
* @returns {Promise<{ credential: CredentialData, user: UserDataWithCredentialCount }>}
* A promise that resolves with an object containing the credential data and user data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async finishAuthenticate(finishAuthenticateParameter, session) {
return await this.apiRequester.request("authenticate/finish", finishAuthenticateParameter, {
schema: yup.object().shape({
credential: credential_data_1.CredentialDataSchema,
user: user_data_1.UserDataWithCredentialCountSchema,
signalAllAcceptedCredentialsOptions: schema_1.SignalAllAcceptedCredentialsOptionsSchema,
signalCurrentUserDetailsOptions: schema_1.SignalCurrentUserDetailsOptionsSchema,
}),
cookie: session,
});
}
/**
* Retrieves the credential with the specified ID belonging to the user with the specified ID.
*
* @param {string} userId - The ID of the user that the credential belongs to.
* @param {string} credentialId - The ID of the credential to retrieve.
* @param {boolean} [withDisabledUser=false] - Whether to include disabled users in the result.
* @param {boolean} [withDisabledCredential=false] - Whether to include disabled credentials in the result.
*
* @returns {Promise<{ user: UserDataWithCredentialCount, credential: CredentialData }>}
* A promise that resolves with an object containing the user data and the credential data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async getCredential(userId, credentialId, withDisabledUser = false, withDisabledCredential = false) {
return await this.apiRequester.request("getCredential", { userId, credentialId, withDisabledUser, withDisabledCredential }, {
schema: yup.object().shape({
user: user_data_1.UserDataWithCredentialCountSchema,
credential: credential_data_1.CredentialDataSchema,
})
});
}
/**
* Updates the specified credential.
*
* @param {CredentialDataUpdateParameter} credential - The credential data for update.
* @param {boolean} [withUpdatedCheck=false] - Whether to check for the updated date.
*
* @returns {Promise<{ user: UserDataWithCredentialCount, credential: CredentialData }>}
* A promise that resolves with an object containing the updated user data and credential data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async updateCredential(credential, withUpdatedCheck = false) {
return await this.apiRequester.request("updateCredential", {
credential,
options: {
withUpdatedCheck,
}
}, {
schema: yup.object().shape({
user: user_data_1.UserDataWithCredentialCountSchema,
credential: credential_data_1.CredentialDataSchema,
})
});
}
/**
* Deletes the credential with the specified ID belonging to the user with the specified ID.
*
* @param {string} userId - The ID of the user that the credential belongs to.
* @param {string} credentialId - The ID of the credential to delete.
*
* @returns {Promise<{ user: UserDataWithCredentialCount, credential: CredentialData, signalUnknownCredentialOptions : SignalUnknownCredentialOptions }>}
* A promise that resolves with an object containing the user data and the credential data.
* If the request fails due to an error in the external API, the promise is rejected with an `FssApiError`.
*/
async deleteCredential(userId, credentialId) {
return await this.apiRequester.request("deleteCredential", { userId, credentialId, }, {
schema: yup.object().shape({
user: user_data_1.UserDataWithCredentialCountSchema,
credential: credential_data_1.CredentialDataSchema,
signalUnknownCredentialOptions: schema_1.SignalUnknownCredentialOptionsSchema,
})
});
}
}
exports.YubiOnFssSdk = YubiOnFssSdk;
//# sourceMappingURL=yubion-fss-sdk.js.map