Skip to content

Commit 1a052bb

Browse files
committed
Add MFA support
1 parent eb9eeb2 commit 1a052bb

6 files changed

Lines changed: 134 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ try {
2828
* Contact fields
2929
* Contact groups
3030
* Hlr
31+
* MFA
3132
* MMS
3233
* Profile
3334
* Sendernames

src/modules/mfa/index.spec.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import nock from 'nock';
2+
3+
import { API_URL } from '../../constants';
4+
import { SMSAPI } from '../../smsapi';
5+
6+
describe('MFA', () => {
7+
afterEach(() => {
8+
nock.cleanAll();
9+
});
10+
11+
describe('generateCode', () => {
12+
it('should generate MFA code without options', async () => {
13+
// given
14+
const smsapi = new SMSAPI('someToken');
15+
const phoneNumber = '+48123456789';
16+
17+
const req = nock(API_URL)
18+
.post('/mfa/codes', {
19+
phone_number: phoneNumber,
20+
})
21+
.reply(200, {
22+
id: 'someId',
23+
code: '123456',
24+
phone_number: phoneNumber,
25+
from: null,
26+
});
27+
28+
// when
29+
const response = await smsapi.mfa.generateCode(phoneNumber);
30+
31+
// then
32+
expect(req.isDone()).toBeTruthy();
33+
expect(response).toEqual({
34+
id: 'someId',
35+
code: '123456',
36+
phoneNumber: phoneNumber,
37+
from: null,
38+
});
39+
});
40+
41+
it('should generate MFA code with options', async () => {
42+
// given
43+
const smsapi = new SMSAPI('someToken');
44+
const phoneNumber = '+48123456789';
45+
const options = {
46+
content: 'Your code is: [%code%]',
47+
fast: true,
48+
from: 'Test',
49+
};
50+
51+
const req = nock(API_URL)
52+
.post('/mfa/codes', {
53+
phone_number: phoneNumber,
54+
content: options.content,
55+
fast: options.fast,
56+
from: options.from,
57+
})
58+
.reply(200, {
59+
id: 'someId',
60+
code: '654321',
61+
phone_number: phoneNumber,
62+
from: 'Test',
63+
});
64+
65+
// when
66+
const response = await smsapi.mfa.generateCode(phoneNumber, options);
67+
68+
// then
69+
expect(req.isDone()).toBeTruthy();
70+
expect(response).toEqual({
71+
id: 'someId',
72+
code: '654321',
73+
phoneNumber: phoneNumber,
74+
from: 'Test',
75+
});
76+
});
77+
});
78+
79+
describe('verifyCode', () => {
80+
it('should verify MFA code', async () => {
81+
// given
82+
const smsapi = new SMSAPI('someToken');
83+
const phoneNumber = '+48123456789';
84+
const code = '123456';
85+
86+
const req = nock(API_URL)
87+
.post('/mfa/codes/verifications', {
88+
phone_number: phoneNumber,
89+
code: code,
90+
})
91+
.reply(204);
92+
93+
// when
94+
await smsapi.mfa.verifyCode(phoneNumber, code);
95+
96+
// then
97+
expect(req.isDone()).toBeTruthy();
98+
});
99+
});
100+
});

src/modules/mfa/index.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { BaseModule } from '../baseModule';
2+
import { MfaGenerateCodeOptions } from './types/MfaGenerateCodeOptions';
3+
import { MfaResponse } from './types/MfaResponse';
4+
5+
export class Mfa extends BaseModule {
6+
async generateCode(number: string, options?: MfaGenerateCodeOptions): Promise<MfaResponse> {
7+
return await this.httpClient.post<MfaResponse>('/mfa/codes', {
8+
phone_number: number,
9+
...options,
10+
});
11+
}
12+
13+
async verifyCode(number: string, code: string): Promise<void> {
14+
return await this.httpClient.post<void>('/mfa/codes/verifications', {
15+
phone_number: number,
16+
code,
17+
});
18+
}
19+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface MfaGenerateCodeOptions {
2+
content?: string;
3+
fast?: boolean;
4+
from?: string;
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface MfaResponse {
2+
id: string;
3+
code: string;
4+
phoneNumber: string;
5+
from: string | null;
6+
}

src/smsapi/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable @typescript-eslint/ban-ts-comment */
22
import { Contacts } from '../modules/contacts';
33
import { Hlr } from '../modules/hlr';
4+
import { Mfa } from '../modules/mfa';
45
import { Mms } from '../modules/mms';
56
import { Profile } from '../modules/profile';
67
import { Sendernames } from '../modules/sendernames';
@@ -23,6 +24,7 @@ export class SMSAPI {
2324

2425
public contacts: Contacts;
2526
public hlr: Hlr;
27+
public mfa: Mfa;
2628
public mms: Mms;
2729
public profile: Profile;
2830
public sendernames: Sendernames;
@@ -39,6 +41,7 @@ export class SMSAPI {
3941

4042
this.contacts = new Contacts(this.getHttpClient());
4143
this.hlr = new Hlr(this.httpClient);
44+
this.mfa = new Mfa(this.httpClient);
4245
this.mms = new Mms(this.httpClient);
4346
this.profile = new Profile(this.httpClient);
4447
this.sendernames = new Sendernames(this.httpClient);

0 commit comments

Comments
 (0)