# External 2FA Server
## User flows
#### Setting up the 2FA SMS for the first time
```
/**
* REGISTER THE USER.
*/
const payload = {
pubKey: <tkey_pub_key>
sig: <signed_using_tkey_priv_key and hash of number>
// number should be in +{country_code}-{number} format.
identifier: <number>
}
const result = await register(payload);
// check if the user is already registered.
if (result.registered) {
// user is already registered.
return;
}
/**
* INITIATE THE VERIFICATION PROCESS.
*/
const result = await start(payload);
saveInSesssionStorage(tracking_id, result.tracking_id);
/**
* VERIFY THE USER & COMPLETE SMS 2FA SETUP PROCESS.
*/
// create a new factor key to setup data in the database.
const factorKey = new generatePrivate().toString(16, 64)
// get the trackingId from sessionStorage and call /verify API.
const res = await verify({ data: { factorKey }, code, address, tracking_id });
// if successfull, add this factorKey and share info in tkey instance.
await coreKitInstance.addFactorKey(factorKey, metadata)
deleteInSessionStorage(tracking_id);
```
### Recover your account on a new device using sms.
```
/**
* INITIATE THE VERIFICATION PROCESS.
*/
const result = await start(payload);
saveInSesssionStorage(tracking_id, result.tracking_id);
/**
* VERIFY THE USER & RECOVER ACCOUNT USING THE FACTOR KEY.
*/
// get the trackingId from sessionStorage and call /verify API.
const res = await verify({ code, address, tracking_id });
// if successfull, get the factor key from the response.
const factorKey = JSON.parse(res.data).factorKey;
await coreKitInstance.inputFactorKey(factorKey)
await coreKitInstance.reconstructTkey()
deleteInSessionStorage(tracking_id);
```
## APIs
### Base Url
https://api-external-safeauth.web3auth.com
### Register the user number
This API is called when user is initiating the sms 2fa for the **first time**.
Endpoint: POST {BASE_API_URL}/api/v1/:factor_type/register
**Request Params**
```
export type FACTOR_TYPE = 'sms' | 'authenticator'
```
**Request Body**
```
export interface IRegisterRequestBody {
pubKey: {
x: string;
y: string;
};
sig: {
r: string;
s: string;
v: string;
}
identifier: string;
}
```
**Response**
```
export interface IRegisterResponse {
// true if the request is handled completely.
success: boolean;
// true, if the number is already registered for the address.
registered: boolean;
// generic message or description of error if any.
message: string;
}
```
**Sample Request Body Code**
```
// sample code to generate the pubKey and sig for the request body.
// privkey should always be unique to a user.
// tkeyPrivKey from the core kit sdk could be used here.
const ec = getEcCrypto();
const privKeyPair: ec.KeyPair = ec.keyFromPrivate(privKey.toString(16, 64));
const pubKey = privKeyPair.getPublic();
const sig = ec.sign(keccak256(Buffer.from(number, "utf8")), Buffer.from(privKey.toString(16, 64), "hex"));
```
### Initiate the verification process.
This API is called when you want to send a verification code to the user number.
*NOTE: This could be used to resend a verification code also but with the same tracking_id.*
**Endpoint:** POST {BASE_API_URL}/api/v1/:factor_type/start
**Request Params**
```
// This only supports sms currently.
// This API is not required for setting up authenticator factor.
export type FACTOR_TYPE = 'sms'
```
**Request**
```
export interface IStartRequestBody {
// `${pubKey.x.toString(16, 64)}{pubkey.y.toString(16, 64)}`
address: string;
// web3auth client id.
client_id: string;
// This is the value you get from the first /start response body.
// Save this in session storage.
// Send this value in next /start requests (page reload, resend code, verify).
// It helps the backend to identify a unique verification session.
tracking_id?: string;
}
```
**Response**
```
export interface IStartResponseBody {
// true if the request is handled completely.
success: boolean;
// unique sms verification session identifier.
// save this in session storage for further use.
tracking_id?: string;
// error code, could be used to handle error messages on the UI.
error_code?: string;
// description of error if any.
message?: string;
}
```
### Verify the number
Call this api if you want to verify the user number using the code entered by the user.
*Note: If the user is setting up the sms factor for the first time, then also send the factorKey with this, so that you can get the factor key from the database.*
**Endpoint:** POST {BASE_API_URL}/api/v1/:factor_type/verify
**Request Params**
```
export type FACTOR_TYPE = 'sms' | 'authenticator'
```
**Request Body**
```
export interface IVerifyRequestBody {
// `${pubKey.x.toString(16, 64)}{pubkey.y.toString(16, 64)}`
address: string;
// web3auth client id.
client_id: string;
// Get it from the session storage, saved previously from the /start request.
tracking_id: string;
// unique identifier, entered by the user
code: string;
// custom metadata you want to set with the user.
// this is only for the first time, when user is setting up the MFA for the first time.
// Send the factorKey in this, which could be in raw format or encrypted using the postbox key.
// This can always be updated in the future as well.
data?: string;
}
```
**Response**
```
export interface IVerifyResponseBody {
// true if the request is handled completely.
success: boolean;
// if success is true, then data will be there.
// It's the same as the data you set previous /verify requests.
data: string;
// error code, could be used to handle error messages on the UI.
error_code?: string;
// description of error if any.
message?: string;
}
```
## Error Codes
Coming soon...