import { PasswordState } from "../state/users/PasswordState";
import { PasscodeState } from "../state/users/PasscodeState";
import {
InvalidPasswordError,
TechnicalError,
TooManyRequestsError,
UnauthorizedError,
} from "../Errors";
import { Client } from "./Client";
import { HttpClientOptions } from "./HttpClient";
/**
* A class to handle passwords.
*
* @constructor
* @category SDK
* @subcategory Clients
* @extends {Client}
*/
class PasswordClient extends Client {
passwordState: PasswordState;
passcodeState: PasscodeState;
// eslint-disable-next-line require-jsdoc
constructor(api: string, options: HttpClientOptions) {
super(api, options);
/**
* @public
* @type {PasswordState}
*/
this.passwordState = new PasswordState(options.cookieName);
/**
* @public
* @type {PasscodeState}
*/
this.passcodeState = new PasscodeState(options.cookieName);
}
/**
* Logs in a user with a password.
*
* @param {string} userID - The UUID of the user.
* @param {string} password - The password.
* @return {Promise<void>}
* @throws {InvalidPasswordError}
* @throws {RequestTimeoutError}
* @throws {TechnicalError}
* @throws {TooManyRequestsError}
* @see https://docs.hanko.io/api/public#tag/Password/operation/passwordLogin
*/
async login(userID: string, password: string): Promise<void> {
const response = await this.client.post("/password/login", {
user_id: userID,
password,
});
if (response.status === 401) {
throw new InvalidPasswordError();
} else if (response.status === 429) {
const retryAfter = response.parseNumericHeader("Retry-After");
this.passwordState.read().setRetryAfter(userID, retryAfter).write();
throw new TooManyRequestsError(retryAfter);
} else if (!response.ok) {
throw new TechnicalError();
}
this.client.processResponseHeadersOnLogin(userID, response);
return;
}
/**
* Updates a password.
*
* @param {string} userID - The UUID of the user.
* @param {string} password - The new password.
* @return {Promise<void>}
* @throws {RequestTimeoutError}
* @throws {UnauthorizedError}
* @throws {TechnicalError}
* @see https://docs.hanko.io/api/public#tag/Password/operation/password
*/
async update(userID: string, password: string): Promise<void> {
const response = await this.client.put("/password", {
user_id: userID,
password,
});
if (response.status === 401) {
this.client.dispatcher.dispatchSessionExpiredEvent();
throw new UnauthorizedError();
} else if (!response.ok) {
throw new TechnicalError();
}
return;
}
/**
* Returns the number of seconds the rate limiting is active for.
*
* @param {string} userID - The UUID of the user.
* @return {number}
*/
getRetryAfter(userID: string) {
return this.passwordState.read().getRetryAfter(userID);
}
}
export { PasswordClient };
Source