# 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...