@accounts/rest-client
Version:
REST client for accounts
258 lines (232 loc) • 6.48 kB
text/typescript
import { type TransportInterface, type AccountsClient } from '@accounts/client';
import {
type User,
type LoginResult,
type CreateUser,
type ImpersonationUserIdentity,
type ImpersonationResult,
type CreateUserResult,
} from '@accounts/types';
import { AccountsJsError } from './accounts-error';
export interface OptionsType {
apiHost: string;
rootPath: string;
}
const headers: { [key: string]: string } = {
'Content-Type': 'application/json',
};
export class RestClient implements TransportInterface {
public client!: AccountsClient;
private options: OptionsType;
constructor(options: OptionsType) {
this.options = options;
}
public async fetch(route: string, args: object, customHeaders: object = {}): Promise<any> {
const fetchOptions = {
headers: {
...headers,
...customHeaders,
},
...args,
};
const res = await fetch(
`${this.options.apiHost}${this.options.rootPath}/${route}`,
fetchOptions
);
if (res) {
if (res.status >= 400 && res.status < 600) {
const { message, code } = await res.json();
// If code is present it means the server returned an `AccountsJsError` error
// so we can safely do the same on the client
if (code) {
throw new AccountsJsError(message, code);
}
throw new Error(message);
}
return res.json();
} else {
throw new Error('Server did not return a response');
}
}
public async authFetch(route: string, args: object, customHeaders: object = {}): Promise<any> {
const tokens = await this.client.refreshSession();
return this.fetch(route, args, {
...customHeaders,
Authorization: tokens ? 'Bearer ' + tokens.accessToken : '',
});
}
public authenticateWithService(
provider: string,
data: any,
customHeaders?: object
): Promise<boolean> {
const args = {
method: 'POST',
body: JSON.stringify({
...data,
}),
};
return this.fetch(`${provider}/verifyAuthentication`, args, customHeaders);
}
public loginWithService(
provider: string,
data: any,
customHeaders?: object
): Promise<LoginResult> {
const args = {
method: 'POST',
body: JSON.stringify({
...data,
}),
};
return this.fetch(`${provider}/authenticate`, args, customHeaders);
}
public impersonate(
accessToken: string,
impersonated: ImpersonationUserIdentity,
customHeaders?: object
): Promise<ImpersonationResult> {
const args = {
method: 'POST',
body: JSON.stringify({
accessToken,
impersonated,
}),
};
return this.fetch('impersonate', args, customHeaders);
}
public refreshTokens(
accessToken: string,
refreshToken: string,
customHeaders?: object
): Promise<LoginResult> {
const args = {
method: 'POST',
body: JSON.stringify({
accessToken,
refreshToken,
}),
};
return this.fetch('refreshTokens', args, customHeaders);
}
public logout(customHeaders?: object): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({}),
};
return this.authFetch('logout', args, customHeaders);
}
public async getUser(customHeaders?: object): Promise<User> {
const args = {
method: 'POST',
body: JSON.stringify({}),
};
return this.authFetch('user', args, customHeaders);
}
public async createUser(user: CreateUser, customHeaders?: object): Promise<CreateUserResult> {
const args = {
method: 'POST',
body: JSON.stringify({ user }),
};
return this.fetch('password/register', args, customHeaders);
}
public resetPassword(
token: string,
newPassword: string,
customHeaders?: object
): Promise<LoginResult | null> {
const args = {
method: 'POST',
body: JSON.stringify({
token,
newPassword,
}),
};
return this.fetch('password/resetPassword', args, customHeaders);
}
public verifyEmail(token: string, customHeaders?: object): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({
token,
}),
};
return this.fetch('password/verifyEmail', args, customHeaders);
}
public sendVerificationEmail(email: string, customHeaders?: object): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({
email,
}),
};
return this.fetch('password/sendVerificationEmail', args, customHeaders);
}
public sendResetPasswordEmail(email: string, customHeaders?: object): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({
email,
}),
};
return this.fetch('password/sendResetPasswordEmail', args, customHeaders);
}
public addEmail(newEmail: string, customHeaders?: object): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({
newEmail,
}),
};
return this.authFetch('password/addEmail', args, customHeaders);
}
public changePassword(
oldPassword: string,
newPassword: string,
customHeaders?: object
): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({
oldPassword,
newPassword,
}),
};
return this.authFetch('password/changePassword', args, customHeaders);
}
public getTwoFactorSecret(customHeaders?: object): Promise<any> {
const args = {
method: 'POST',
};
return this.fetch('password/twoFactorSecret', args, customHeaders);
}
public twoFactorSet(secret: any, code: string, customHeaders?: object): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({
secret,
code,
}),
};
return this.authFetch('password/twoFactorSet', args, customHeaders);
}
public twoFactorUnset(code: string, customHeaders?: object): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({
code,
}),
};
return this.authFetch('password/twoFactorUnset', args, customHeaders);
}
public requestMagicLinkEmail(email: string, customHeaders?: object): Promise<void> {
const args = {
method: 'POST',
body: JSON.stringify({
email,
}),
};
return this.fetch('magiclink/requestMagicLinkEmail', args, customHeaders);
}
}
export default RestClient;