diff --git a/README.md b/README.md index 97a4d7f..da1368d 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,9 @@ A simple way to send and verify verification code with SMS, Email, Telegram and etc. -- [x] Send verify code -- [x] Verify a code +- [x] Send verify code. +- [x] Verify a code. +- [x] VerifyBotAuth. ## Supported Providers @@ -13,11 +14,12 @@ A simple way to send and verify verification code with SMS, Email, Telegram and ## Usages -- Create a verify message and send it to the target +### Verify Feature + +- Create a verify message and send it to the target. ```typescript const API_KEY = 'vm_gX9WwSdKatMNdpUClLU0IfCx575tvdoeQ'; - const sdk = Verifyme.create(VerifymeOptions.builder().apiKey(API_KEY).build()); const request = CreateVerifyRequest.builder() @@ -31,7 +33,7 @@ console.log('Request: ', request); console.log('Response: ', response); ``` -- Verify the message +- Verify the message. ```typescript const request = VerifyMessageRequest.builder() @@ -44,6 +46,32 @@ console.log('Request: ', request); console.log('Response: ', response); ``` +### VerifyBotAuth Feature + +- Create an auth state request with the target. + +```typescript +const API_KEY = 'vm_gX9WwSdKatMNdpUClLU0IfCx575tvdoeQ'; +const sdk = Verifyme.create(VerifymeOptions.builder().apiKey(API_KEY).build()); + +const request: VerifyBotAuthCreate = { + target: '+855769995149', + type: 'telegram_bot', +}; + +const response = await sdk.botAuth().auth(request); +console.log('Request: ', request); +console.log('Response: ', response); +``` + +- Get the auth state. + +```typescript +const result = await sdk.botAuth().state(response.state!); +console.log('State: ', state); +console.log('Result: ', result); +``` + ### Contributors - Sambo Chea diff --git a/package-lock.json b/package-lock.json index 358c5a6..e8da01d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cubetiq/verifyme", - "version": "0.0.4", + "version": "0.1.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cubetiq/verifyme", - "version": "0.0.4", + "version": "0.1.5", "license": "ISC", "dependencies": { "axios": "^1.6.2" diff --git a/package.json b/package.json index 228afa4..4662b29 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cubetiq/verifyme", - "version": "0.0.4", + "version": "0.1.5", "description": "A simple way to send and verify verification code with SMS, Email, Telegram and etc.", "main": "dist/index.js", "private": false, diff --git a/src/model.ts b/src/model.ts index ab7c8a0..3506002 100644 --- a/src/model.ts +++ b/src/model.ts @@ -7,6 +7,9 @@ enum Provider { type ProviderType = 'telegram' | 'verifybot' | 'sms' | 'email'; +export type VerifyBotAuthType = 'telegram_bot' | 'qr_code'; +export type VerifyBotAuthStatus = 'pending' | 'verified' | 'expired' | 'rejected'; + class CreateVerifyRequest { provider?: Provider | ProviderType | string; // telegram, verifybot, sms, email target?: string; // phone, email, telegram chat id, etc. @@ -41,7 +44,7 @@ class CreateVerifyRequestBuilder { private _timeout?: number; private _template?: string; - constructor() {} + constructor() { } provider( provider: Provider | ProviderType | string | undefined @@ -113,7 +116,7 @@ class VerifyMessageRequestBuilder { private _token?: string; private _code?: string; - constructor() {} + constructor() { } token(token: string | undefined): VerifyMessageRequestBuilder { this._token = token; @@ -182,7 +185,7 @@ class VerifymeOptionsBuilder { private _apiKey?: string; private _connectionTimeout?: number; - constructor() {} + constructor() { } url(url: string | undefined): VerifymeOptionsBuilder { this._url = url; @@ -210,6 +213,65 @@ class VerifymeOptionsBuilder { } } +export class VerifyBotAuthCreate { + target?: string; + type?: VerifyBotAuthType | string; + + constructor({ + target, + type, + }: { + target?: string; + type?: VerifyBotAuthType | string; + }) { + this.target = target; + this.type = type; + } + + static builder(): VerifyBotAuthCreateBuilder { + return new VerifyBotAuthCreateBuilder(); + } +} + +export class VerifyBotAuthCreateBuilder { + private _target?: string; + private _type?: VerifyBotAuthType | string; + + constructor() { } + + target(target: string | undefined): VerifyBotAuthCreateBuilder { + this._target = target; + return this; + } + + type(type: VerifyBotAuthType | string | undefined): VerifyBotAuthCreateBuilder { + this._type = type; + return this; + } + + build(): VerifyBotAuthCreate { + return new VerifyBotAuthCreate({ + target: this._target, + type: this._type, + }); + } +} + +export interface VerifyBotAuthCreated { + state?: string; + exp?: number; + link?: string; + qr_link?: string; + error?: string; +} + +export interface VerifyBotAuthGetState { + target?: string; + status?: VerifyBotAuthStatus | string; + data?: any; + error?: string; +} + export { Provider, ProviderType, diff --git a/src/service.ts b/src/service.ts index 424854f..d709761 100644 --- a/src/service.ts +++ b/src/service.ts @@ -85,6 +85,89 @@ class VerifymeService { }; }); } + + ///////// VerifyBotAuth ///////// + async createBotAuth( + body: any, + headers?: any, + timeout?: number + ): Promise { + const config: AxiosRequestConfig = { + method: 'POST', + url: `${this.url}/botauth`, + data: body, + headers: headers, + timeout: timeout ? timeout * 1000 : undefined, + }; + + return axios(config) + .then((response) => response.data) + .catch((error) => { + if (error.response) { + console.debug( + `CreateBotAuth Error: ${JSON.stringify( + error.response.data + )}` + ); + + return { + ...error.response.data, + }; + } else if (error.request) { + console.debug( + `CreateBotAuth Error: ${JSON.stringify(error.request)}` + ); + + return { + error: error.request, + }; + } + + return { + error: error?.message ?? 'Unknown error', + }; + }); + } + + async getBotAuth( + state: string, + headers?: any, + timeout?: number + ): Promise { + const config: AxiosRequestConfig = { + method: 'GET', + url: `${this.url}/botauth/${state}`, + headers: headers, + timeout: timeout ? timeout * 1000 : undefined, + }; + + return axios(config) + .then((response) => response.data) + .catch((error) => { + if (error.response) { + console.debug( + `GetBotAuth Error: ${JSON.stringify(error.response.data)}` + ); + + return { + ...error.response.data, + }; + } else if (error.request) { + console.debug( + `GetBotAuth Error: ${JSON.stringify(error.request)}` + ); + + return { + error: error.request, + }; + } + + return { + error: error?.message ?? 'Unknown error', + }; + }); + } + ///////// VerifyBotAuth ///////// } export { VerifymeService }; diff --git a/src/verifybotauth.ts b/src/verifybotauth.ts new file mode 100644 index 0000000..768fd3f --- /dev/null +++ b/src/verifybotauth.ts @@ -0,0 +1,29 @@ +import { VerifyBotAuthCreate, VerifyBotAuthCreated, VerifyBotAuthGetState } from "./model"; +import { VerifymeService } from "./service"; + +export class VerifyBotAuth { + private readonly _logger = console; + private readonly _service: VerifymeService; + + constructor(service: VerifymeService) { + this._service = service; + } + + async auth(request: VerifyBotAuthCreate): Promise { + this._logger.info(`[VerifyBotAuth] Creating auth with target: ${request.target}`); + + const response = await this._service.createBotAuth(request); + return response; + } + + async state(state: string): Promise { + if (!state) { + throw new Error('State is required'); + } + + this._logger.info(`[VerifyBotAuth] Getting auth state with state: ${state}`); + + const response = await this._service.getBotAuth(state); + return response; + } +} \ No newline at end of file diff --git a/src/verifyme.ts b/src/verifyme.ts index bf5aced..c4c91cb 100644 --- a/src/verifyme.ts +++ b/src/verifyme.ts @@ -1,18 +1,20 @@ import { CreateVerifyRequest, CreateVerifyResponse, VerifyMessageRequest, VerifyMessageResponse, VerifymeOptions } from "./model"; import { VerifymeService } from "./service"; import { getSystemHostname, getSystemUsername } from "./util"; +import { VerifyBotAuth } from "./verifybotauth"; export class Verifyme { private static readonly _logger = console; private static readonly NAME = 'verifyme'; - private static readonly VERSION = '0.0.4'; - private static readonly VERSION_CODE = '2'; + private static readonly VERSION = '0.1.5'; + private static readonly VERSION_CODE = '3'; private static readonly DEFAULT_URL = 'https://verifyme-api.cubetiq.app'; private static readonly API_KEY_HEADER_PREFIX = 'x-api-key'; private static readonly DEFAULT_CONNECT_TIMEOUT = 60; // seconds private _options!: VerifymeOptions; private _service!: VerifymeService; + private _botAuth!: VerifyBotAuth; constructor(options: VerifymeOptions) { if (!options.apiKey) { @@ -26,6 +28,9 @@ export class Verifyme { // Initialize service this._service = new VerifymeService(this._options.url); + // Initialize bot auth + this._botAuth = new VerifyBotAuth(this._service); + Verifyme._logger.log(`[Verifyme] Initialized SDK Version: ${Verifyme.VERSION}-${Verifyme.VERSION_CODE}`); } @@ -37,7 +42,7 @@ export class Verifyme { const sender = getSystemUsername() ?? 'unknown'; // User agent to request - const userAgent = `verifyme-sdk-node/${Verifyme.VERSION}-${Verifyme.VERSION_CODE} (${hostname}:${sender})`; + const userAgent = `${Verifyme.NAME}-sdk-node/${Verifyme.VERSION}-${Verifyme.VERSION_CODE} (${hostname}:${sender})`; Verifyme._logger.info(`[Verifyme] User agent: ${userAgent}`); const headers: Record = { @@ -71,6 +76,10 @@ export class Verifyme { return response; } + botAuth(): VerifyBotAuth { + return this._botAuth; + } + static create(options: VerifymeOptions): Verifyme { return new Verifyme(options); } diff --git a/tests/verifyme.test.ts b/tests/verifyme.test.ts index 0a4bd77..796a3f4 100644 --- a/tests/verifyme.test.ts +++ b/tests/verifyme.test.ts @@ -1,4 +1,4 @@ -import { CreateVerifyRequest, VerifyMessageRequest, Verifyme, VerifymeOptions } from '../src/index'; +import { CreateVerifyRequest, VerifyBotAuthCreate, VerifyMessageRequest, Verifyme, VerifymeOptions } from '../src/index'; const API_KEY = 'vm_gX9WwSdKatMNdpUClLU0IfCx575tvdoeQ' @@ -12,6 +12,10 @@ test('Verifyme sdk should be defined', () => { expect(sdk).toBeDefined(); }); +test('VerifyBotAuth should be defined', () => { + expect(sdk.botAuth()).toBeDefined(); +}) + test('Verifyme sdk should be able to create a verify code and send to the target', async () => { const request = CreateVerifyRequest.builder() .provider("email") @@ -76,4 +80,46 @@ test('Verifyme sdk should be able to verify with token and code', async () => { // expect(response.success).toBeDefined(); // expect(response.success).not.toBeNull(); // expect(response.success).toBe(true); +}) + +let state: string | undefined; + +test('VerifyBotAuth should be able to create a state', async () => { + const request: VerifyBotAuthCreate = { + target: '+855769995149', + type: 'telegram_bot' + } + + const response = await sdk.botAuth().auth(request); + console.log("Request: ", request); + console.log("Response: ", response); + + expect(request.target).toBeDefined(); + expect(request.target).not.toBeNull(); + expect(request.type).toBeDefined(); + expect(request.type).not.toBeNull(); + + expect(response.state).toBeDefined(); + expect(response.state).not.toBeNull(); + expect(response.state).not.toBe(''); + + state = response.state; +}) + +test('VerifyBotAuth should be able to get state', async () => { + const result = await sdk.botAuth().state(state!); + console.log("State: ", state); + console.log("Result: ", result); + + expect(result.target).toBeDefined(); + expect(result.target).not.toBeNull(); + expect(result.target).not.toBe(''); + + expect(result.status).toBeDefined(); + expect(result.status).not.toBeNull(); + expect(result.status).not.toBe(''); + expect(result.status).toBe('pending'); + + expect(result.data).toBeDefined(); + expect(result.data).toBeNull(); }) \ No newline at end of file