const axios = require("axios");
const ROOT = process.env.NODE_ENV === "PRODUCTION" ? "https://api.carbon.money" : "https://sandbox.carbon.money";
Google 2FA is required once a user passes KYC.
We believe Google 2FA is very important because it prevent unauthorized access to your accounts. Google 2FA is also more secure than SMS-2FA because of recent sim-swapping hacks. Sim-swapping can reset your iCloud, your email and all of your cryptocurrency accounts.
2FA can also be enabled at any time to protect a user's account. The steps to enabling 2FA is to first:
-
Create a 2FA
Once the user has linked the 2FA with his/her Google Authentication (iOS or Android), they need to send in the real time 6-digit token to step 2. -
Enabled 2FA
If the token checks true, 2FA has successfully been added. -
Disable 2FA (optional)
A user may also disable 2FA if they pass in their token. Remember, all KYC-ed users are required to have 2FA for account safety purposes.
Super JWT or Secret Key Required
2FA Requirement Exception
To work through removing the 2FA requirement for your integration, please reach out to [email protected] Unless your KYC/AML and anti-fraud are already very stringent, it is very unlikely we will approve waiving this requirement.
1: Create 2FA
Request Parameters
| Parameters | Access | Description |
|---|---|---|
| twoFactorIssuer | optional | When you create a google 2FA, your users will see a name corresponding to the 6 digit code. The default value is Carbon2FA but you can set this to something more relevant |
| contactId | required |
// legacy auth that will be deprecated in our v2 api
/*
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
*/
// we strongly recommend using your secret key to more securely authenticate your superuser instead
let secretKey = 'sk_test_A41Hm6IY3Q5LJ7ham34Zpkcj';
let headers = {
headers: {
Authorization: `Bearer ${secretKey}`
}
};
let url = `${ROOT}/v1/auth/create2fa?contactId=ab5bb41b-5979-4a54-b734-23eb9076188e&twoFactorIssuer=CompanyName`;
axios.get(url, headers).then(result => console.log(result)).catch(err => console.log(err));
{
"message":"Successfully created 2fa!",
"code": 200,
"details":{
"qrCode":"data:image/png;base64,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",
"manual":"KA7F4SJTKYSUSL2RHZXSGUCMKVDSK6RYJFTSQMBVONGVONKCJIUA"
}
}
// 401
{
'message': 'You must disable 2fa before you can create a new 2fa.',
'code': 403
}
// 409
{
'message': 'You cannot enable 2fa again as it is already set.',
'code': 409
}
// 500
{
'message': 'Error enabling 2fa.',
'code': 500
}
Response Parameters
| Response | Description |
|---|---|
| qrCode | If you add this as the source for a tag on the front end, you can generate a qrCode users can scan. |
| manual | Your users can also add this auth using a manual entry for Google 2FA. |
Video Overview of Google 2FA
2: Enable 2FA
// legacy auth that will be deprecated in our v2 api
/*
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
*/
// we strongly recommend using your secret key to more securely authenticate your superuser instead
let secretKey = 'sk_test_A41Hm6IY3Q5LJ7ham34Zpkcj';
let headers = {
headers: {
Authorization: `Bearer ${secretKey}`
}
};
let url = `${ROOT}/v1/auth/enable2fa`;
let data = {
token: '1234565',
contactId: 'ab5bb41b-5979-4a54-b734-23eb9076188e'
}
axios.post(url, data, headers).then(result => console.log(result)).catch(err => console.log(err));
{
'message': 'Successfully enabled 2fa!',
"code": 200
}
// 401
{
'message': 'Google 2FA requires token to be passed in.',
'code': 401
}
// 401
{
'message': 'Google 2FA failed.',
'code': 401
}
// 500
{
'message': 'Error enabling 2fa.',
'code': 500
}
3: Disable 2FA
// legacy auth that will be deprecated in our v2 api
/*
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
*/
// we strongly recommend using your secret key to more securely authenticate your superuser instead
let secretKey = 'sk_test_A41Hm6IY3Q5LJ7ham34Zpkcj';
let headers = {
headers: {
Authorization: `Bearer ${secretKey}`
}
};
let url = `${ROOT}/v1/auth/disable2fa`;
let data = {
token: '1234565',
contactId: 'ab5bb41b-5979-4a54-b734-23eb9076188e'
}
axios.post(url, data, headers).then(result => console.log(result)).catch(err => console.log(err));
{
"message": "Successfully disabled 2fa!",
"code": 200
}
// 401
{
"message": "Google 2fa requires token to be passed in.",
"code": 401
}
// 401
{
"message": "Google 2fa failed.",
"code": 401
}
// 500
{
"message": "Error disabling 2fa.",
"code": 500
}
4: Delete 2FA
// legacy auth that will be deprecated in our v2 api
/*
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
*/
// we strongly recommend using your secret key to more securely authenticate your superuser instead
let secretKey = 'sk_test_A41Hm6IY3Q5LJ7ham34Zpkcj';
let headers = {
headers: {
Authorization: `Bearer ${secretKey}`
}
};
let url = `${ROOT}/v1/auth/delete2fa`;
let data = {
contactId: 'ab5bb41b-5979-4a54-b734-23eb9076188e'
}
axios.post(url, data, headers).then(result => console.log(result)).catch(err => console.log(err));
{
"message": "Successfully deleted 2fa!",
"code": 200
}
5. Get Current 2FA Status
// legacy auth that will be deprecated in our v2 api
/*
let jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlMzE3YjdlNy0yMzQ1LTQ0MWMtODA0Ni1kYjgxNTkyYmEyN2YiLCJzdXBlclVzZXIiOnRydWUsImNvbnRhY3QiOmZhbHNlLCJlbWFpbCI6ImRhbmllbEBjYXJib24ubW9uZXkiLCJpYXQiOjE1NTczMjc5MTR9.WZnSR5N1FebmT9nMu97PJvku49NY0jk4aKVPKm_1MlM';
*/
// we strongly recommend using your secret key to more securely authenticate your superuser instead
let secretKey = 'sk_test_A41Hm6IY3Q5LJ7ham34Zpkcj';
let headers = {
headers: {
Authorization: `Bearer ${secretKey}`
}
};
let url = `${ROOT}/v1/auth/2fa?contactId=ab5bb41b-5979-4a54-b734-23eb9076188e`;
axios.get(url, headers).then(result => console.log(result)).catch(err => console.log(err));
// 2fa is enabled
{
"message": "2FA is true.",
"code": 200,
"status": true
}
// 2fa is disabled
{
"message": "2FA is false.",
"code": 200,
"status": false
}
// 500
{
message: 'Error getting 2fa.',
code: 500
]
Updated 5 months ago