pratik-auth-sdk-test
Version:
Arvasit Authentication SDK for Node.js
539 lines (481 loc) • 16.7 kB
text/typescript
import axios, { AxiosInstance } from 'axios';
import crypto from 'crypto';
import {
AuthHeaders,
CheckCredentialRequest,
CheckCredentialResponse,
CheckUserNameRequest,
CredentialForForgotPasswordRequest,
DisableTwoFARequest,
EnterCredentialForForgotPasswordResponse,
ForgotPasswordSendOTPRequest,
GenerateQRCodeAndSecretFor2FARequest,
GenerateQrCodeAndSecretFor2FAResponse,
GenerateRecoveryCodesRequest,
ListOfRecoveryCodeRequest,
ListOfRecoveryCodeResponse,
ListOfSecretKeysRequest,
ListOfSecretKeysResponse,
LoginActivityCountResponse,
LoginActivityCountsRequest,
LoginActivityDetailsRequest,
LoginActivityDetailsResponse,
LoginRequest,
LoginResponse,
LogoutRequest,
OtpLoginRequest,
RecoveryCodeLoginRequest,
RefreshAccessTokenRequest,
RefreshTokenResponse,
RemoveTwoFADeviceRequest,
SignupRequest,
SignupResponse,
SuggestUsernameRequest,
TwoFALoginRequest,
UpdatePasswordRequest,
ValidateForgetPasswordTokenRequest,
VerifyForgotPasswordOTPRequest,
VerifyQRCodeAndSecretFor2FARequest,
VerifyTokenSetupPasswordRequest,
} from './auth-types';
import { DateTime } from 'luxon';
export interface AuthServiceConfig {
url: string;
publicKey: string;
secretKey: string;
}
export class AuthService {
private client: AxiosInstance;
private config: AuthServiceConfig;
constructor(config: AuthServiceConfig) {
this.config = config;
// Create an axios instance with base configuration
this.client = axios.create({
baseURL: config.url,
headers: {
'Content-Type': 'application/json',
'X-Public-Key': config.publicKey,
'X-Secret-Key': config.secretKey,
},
});
}
/**
* Generates headers for authentication requests.
* @param path - The endpoint path to include in signature data.
* @returns Authentication headers.
*/
private getAuthHeaders(accessToken?: string): AuthHeaders {
const timestamp = DateTime.now().toMillis().toString();
const signatureData = `${this.config.publicKey}${timestamp}`;
const signature = crypto
.createHmac('sha256', this.config.secretKey)
.update(signatureData)
.digest('hex');
return {
'public-key': this.config.publicKey,
timestamp,
signature,
...(accessToken && { Authorization: `Bearer ${accessToken}` }),
};
}
/**
* Signup.
* @param params - The params is used for sign in.
* @returns A promise that resolves to the create a user.
*/
async signup(params: SignupRequest): Promise<SignupResponse> {
const path = '/auth/signup';
const headers = this.getAuthHeaders();
const response = await this.client.post<SignupResponse>(path, params, {
headers,
});
return response.data;
}
/**
* Suggest username which is not present in the system.
* @param params - An Object of firstName and lastName.
* @returns A promise that resolves to give available username.
*/
async suggestUsername(params: SuggestUsernameRequest): Promise<string[]> {
const path = '/user/usernames';
const headers = this.getAuthHeaders();
const response = await this.client.get<string[]>(path, {
params,
headers,
});
return response.data;
}
/**
* check available username which is not present in the system.
* @param params - An Object of username.
* @returns A promise that resolves to boolean.
*/
async checkAvailableUserName(params: CheckUserNameRequest): Promise<boolean> {
const path = '/user/checkUsername';
const headers = this.getAuthHeaders();
const response = await this.client.get<boolean>(path, {
params,
headers,
});
return response.data;
}
/**
* Check the type of credential (e.g., email or phone).
* @param credential - The credential to check.
* @returns A promise that resolves to the credential check result.
*/
async checkCredential({ credential }: CheckCredentialRequest): Promise<CheckCredentialResponse> {
const path = '/auth/checkCredential';
const headers = this.getAuthHeaders();
const response = await this.client.get<CheckCredentialResponse>(path, {
params: {
credential,
},
headers,
});
return response.data;
}
/**
* Login using a password.
* @param params - An object containing credential and password.
* @returns A promise that resolves to the login response.
*/
async loginWithPassword(params: LoginRequest): Promise<LoginResponse> {
const path = '/auth/loginWithPassword';
const headers = this.getAuthHeaders();
const response = await this.client.post<LoginResponse>(path, params, {
headers,
});
return response.data;
}
/**
* Login using an OTP (One-Time Password).
* @param params - An object containing credential and OTP.
* @returns A promise that resolves to the login response.
*/
async loginWithOtp(params: OtpLoginRequest): Promise<LoginResponse> {
const path = '/auth/loginWithOtp';
const headers = this.getAuthHeaders();
const response = await this.client.post<LoginResponse>(path, params, {
headers,
});
return response.data;
}
/**
* Send an OTP (One-Time Password) for login.
* @param params - An object containing credential.
* @returns A promise that resolves to send OTP on credential.
*/
async sendOtpForLogin({ credential }: CheckCredentialRequest): Promise<CheckCredentialResponse> {
const path = '/auth/sendOtpForLogin';
const headers = this.getAuthHeaders();
const response = await this.client.get<CheckCredentialResponse>(path, {
params: {
credential,
},
headers,
});
return response.data;
}
/**
* Login using two factor authentication.
* @param params - An object containing credential and OTP.
* @returns A promise that resolves to the login response.
*/
async verifyTwoFactorAuthenticationToLogin(params: TwoFALoginRequest): Promise<LoginResponse> {
const path = '/auth/verifyTwoFactorAuthToken';
const headers = this.getAuthHeaders();
const response = await this.client.post<LoginResponse>(path, params, {
headers,
});
return response.data;
}
/**
* Login using recovery code.
* @param params - An object containing credential and OTP.
* @returns A promise that resolves to the login response.
*/
async loginWithRecoveryCode(params: RecoveryCodeLoginRequest): Promise<LoginResponse> {
const path = '/auth/recoveryCodeToLogin';
const headers = this.getAuthHeaders();
const response = await this.client.post<LoginResponse>(path, params, {
headers,
});
return response.data;
}
/**
* logout is to remove session of user.
* @param params - An object containing of access token.
* @returns A promise that resolves to boolean.
*/
async logout(params: LogoutRequest): Promise<string> {
const path = '/auth/userLogout';
const headers = this.getAuthHeaders();
const response = await this.client.post<string>(path, params, {
headers,
});
return response.data;
}
/**
* Enter credential for forgot password to get type email or phone to send otp on.
* @param Credential - The credential for forgot password.
* @returns A promise that resolves to send otp type with masked email and phone.
*/
async enterCredentialForForgotPassword({
credential,
}: CredentialForForgotPasswordRequest): Promise<EnterCredentialForForgotPasswordResponse> {
const path = '/auth/enterCredentialForForgotPassword';
const headers = this.getAuthHeaders();
const response = await this.client.get<EnterCredentialForForgotPasswordResponse>(path, {
params: {
credential,
},
headers,
});
return response.data;
}
/**
* Send otp on credential for forgot password authorization.
* @param params - An object containing credential and OTP.
* @returns A promise that resolves to give token to set new password.
*/
async forgotPasswordSendOTP(params: ForgotPasswordSendOTPRequest): Promise<string> {
const path = '/auth/forgotPasswordSendOTP';
const headers = this.getAuthHeaders();
const response = await this.client.post<string>(path, params, {
headers,
});
return response.data;
}
/**
* Verify otp for forget password reset.
* @param params - An object containing credential and OTP.
* @returns A promise that resolves to give token to set new password.
*/
async verifyForgotPasswordOtp(params: VerifyForgotPasswordOTPRequest): Promise<string> {
const path = '/auth/verifyForgotPasswordOtp';
const headers = this.getAuthHeaders();
const response = await this.client.post<string>(path, params, {
headers,
});
return response.data;
}
/**
* Check forgot password generated token is valid for setting up new password.
* @param token - An object containing token and password.
* @returns A promise that resolves to true.
*/
async validateForgetPasswordToken(params: ValidateForgetPasswordTokenRequest): Promise<boolean> {
const path = '/auth/validateForgetPasswordToken';
const headers = this.getAuthHeaders();
const response = await this.client.get<boolean>(path, {
params,
headers,
});
return response.data;
}
/**
* Check forgot password generated token is valid and set new password.
* @param params - Token generated after verifying forgot password otp.
* @returns A promise that resolves to token is valid or not.
*/
async verifyTokenSetupPassword(params: VerifyTokenSetupPasswordRequest): Promise<boolean> {
const path = '/auth/verifyTokenSetupPassword';
const headers = this.getAuthHeaders();
const response = await this.client.post<boolean>(path, params, {
headers,
});
return response.data;
}
/**
* Update.
* @param params - An object containing credential and OTP.
* @returns A promise that resolves to give true.
*/
async updatePassword(params: UpdatePasswordRequest): Promise<boolean> {
const path = '/auth/updatePassword';
const headers = this.getAuthHeaders();
const response = await this.client.put<boolean>(path, params, {
headers,
});
return response.data;
}
/**
* Send otp on credential for forgot password authorization.
* @param params - An object containing accessToken.
* @returns A promise that resolves to give token to set new password.
*/
async generateRecoveryCodes(params: GenerateRecoveryCodesRequest): Promise<LoginResponse> {
const { accessToken } = params;
const path = '/secret-keys/generateRecoveryCodes';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.post<LoginResponse>(
path,
{},
{
headers,
},
);
return response.data;
}
/**
* Send refresh access token to get new access token for authorization.
* @param params - An object containing of access token.
* @returns A promise that resolves to give new access token for api authorization.
*/
async refreshAccessToken(params: RefreshAccessTokenRequest): Promise<RefreshTokenResponse> {
const path = '/auth/refreshAccessToken';
const headers = this.getAuthHeaders();
const response = await this.client.get<RefreshTokenResponse>(path, {
params,
headers,
});
return response.data;
}
/**
* Generate qr code and secret to set up two factor authentication.
* @param params - An object containing of access token.
* @returns A promise that resolves to give QR Code Image and Secret key.
*/
async generateQRCodeAndSecretFor2FA(
params: GenerateQRCodeAndSecretFor2FARequest,
): Promise<GenerateQrCodeAndSecretFor2FAResponse> {
const { accessToken } = params;
const path = '/secret-keys/generateQRCodeAndSecretFor2FA';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.post<GenerateQrCodeAndSecretFor2FAResponse>(
path,
{},
{
headers,
},
);
return response.data;
}
/**
* Verify generated qr code and secret to add two factor authentication.
* @param params - An object containing of access token, totp and secret key.
* @returns A promise that resolves to give QR Code Image and Secret key.
*/
async verifyQRCodeAndSecretFor2FA(
params: VerifyQRCodeAndSecretFor2FARequest,
): Promise<GenerateQrCodeAndSecretFor2FAResponse> {
const { accessToken, ...restParams } = params;
const path = '/secret-keys/verifyQrCodeAndSecretFor2FA';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.post<GenerateQrCodeAndSecretFor2FAResponse>(
path,
restParams,
{
headers,
},
);
return response.data;
}
/**
* List of two factor authentication secret of logged in user.
* @param params - An object containing of access token.
* @returns A promise that resolves to give array of 2FA secret keys.
*/
async listOfTwoFASecrets(params: ListOfSecretKeysRequest): Promise<ListOfSecretKeysResponse> {
const { accessToken } = params;
const path = '/secret-keys/listOfTwoFASecrets';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.get<ListOfSecretKeysResponse>(path, {
headers,
});
return response.data;
}
/**
* Remove two factor authentication device of logged in user.
* @param params - An object containing of access token and key i.e secret key.
* @returns A promise that resolves to give array of 2FA secret keys.
*/
async removeTwoFADevice(params: RemoveTwoFADeviceRequest): Promise<string[]> {
const { accessToken, key } = params;
const path = '/secret-keys/removeTwoFADevice';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.delete<string[]>(path, {
params: {
key,
},
headers,
});
return response.data;
}
/**
* Disable two factor authentication of logged in user.
* @param params - An object containing of access token.
* @returns A promise that resolves to give array of 2FA secret keys.
*/
async disableTwoFA(params: DisableTwoFARequest): Promise<boolean> {
const { accessToken } = params;
const path = '/auth/disableTwoFA';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.post<boolean>(
path,
{},
{
headers,
},
);
return response.data;
}
/**
* List of recovery code or security code of logged in user.
* @param params - An object containing of access token.
* @returns A promise that resolves to give array of 2FA secret keys.
*/
async listOfRecoveryCode(params: ListOfRecoveryCodeRequest): Promise<ListOfRecoveryCodeResponse> {
const { accessToken } = params;
const path = '/secret-keys/listOfRecoveryCode';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.get<ListOfRecoveryCodeResponse>(path, {
headers,
});
return response.data;
}
/**
* Get login activity counts.
* @param params - An object containing of pagination.
* @returns A promise that resolves to give new access token for api authorization.
*/
async loginActivityCounts(
params: LoginActivityCountsRequest,
): Promise<LoginActivityCountResponse> {
const { accessToken, ...restData } = params;
const path = '/logging-events/loginActivityCount';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.get<LoginActivityCountResponse>(path, {
params: restData,
headers,
});
return response.data;
}
/**
* Get login activity details.
* @param params - An object containing of pagination.
* @returns A promise that resolves to give new access token for api authorization.
*/
async loginActivityDetails(
params: LoginActivityDetailsRequest,
): Promise<LoginActivityDetailsResponse> {
const { accessToken, ...restData } = params;
const path = '/logging-events/loginActivityDetails';
const headers = this.getAuthHeaders(accessToken);
const response = await this.client.get<LoginActivityDetailsResponse>(path, {
params: restData,
headers,
});
return response.data;
}
private handleError(error: any): Error {
if (axios.isAxiosError(error)) {
// Handle Axios errors
const message = error.response?.data?.message || error.message;
return new Error(`Auth Service Error: ${message}`);
}
return error;
}
}
export default AuthService;