UNPKG

@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
"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