0

I'm using Infobip free trial account and trying to implement the two-factor authentication SMS feature (following this Infobip SMS2FA) in my node js app. So, I am facing an error which I'm guesing is an issue that it cant't get to the API. But my API credentials and URL are okay:

{
  requestError: {
    serviceException: { messageId: 'UNAUTHORIZED', text: 'Invalid login details' }
  }
}

Here's the code. Check inside the signup router post:

const express = require("express");
const { createNewUser, authenticateUser } = require("./controller");
const router = express.Router();
const auth = require("../../middleware/auth");
const fetch = require('node-fetch');

const SENDER = 'InfoSMS_1';
const MESSAGE_TEXT = 'Here is the PIN';
const API_KEY = '<>';
const API_BASE_URL = '<>';
const API_2FA_BASE_URL = '<>';
const API_PIN_URL = '<>';

// protected route
router.get("/private_data", auth, (req, res) => {
    res.status(200).send(`You're in the private territory of ${req.currentUser.phone}`);
});

// Signin
router.post("/", async (req, res) => {
    try {
        let { phone, password } = req.body;
        phone = phone.trim();
        password = password.trim();

        if (!(phone && password)) {
            throw Error("Empty credentials");
        }
        const authenticatedUser = await authenticateUser({ phone, password });
        res.status(200).json(authenticatedUser);
    } catch (error) {
        res.status(400).send(error.message);
    }
});

// Signup
router.post("/signup", async (req, res) => {
    try {
        let { name, phone, password } = req.body;
        name = name.trim();
        phone = phone.trim();
        password = password.trim();

        if (!(name && phone && password)) {
            throw Error("Empty input fields!");
        } else if (!/^[a-zA-Z]*$/.test(name)) {
            throw Error("Invalid Name entered");
        } else if (!(/^\d{7,}$/).test(phone.replace(/[\s()+\-\.]|ext/gi, ''))) {
            throw Error("Invalid Phone number");
        } else if (password.length < 8) {
            throw Error("Password is too short");
        } else {
            // Good credentials
            // Create new user
            const newUser = await createNewUser({
                name,
                phone,
                password,
            });

            // Call Infobip API to create a new 2FA application
            const infobipSettings = {
                method: 'POST',
                headers: {
                    'Authorization': API_KEY,
                    'Content-Type': 'application/json',
                    'Accept': 'application/json'
                },
                body: JSON.stringify({
                    name: '2fa SMS demo application',
                    enabled: true,
                    configuration: {
                        pinAttempts: 5,
                        allowMultiplePinVerifications: true,
                        pinTimeToLive: '10m',
                        verifyPinLimit: '2/4s',
                        sendPinPerApplicationLimit: '5000/12h',
                        sendPinPerPhoneNumberLimit: '2/1d'
                    }
                })
            };
            const response = await fetch(API_2FA_BASE_URL, infobipSettings);
            const data = await response.json();
            const applicationId = data.id; // Get the application ID from Infobip API response
            console.log(`Application ID: ${applicationId}`);

            // Message template
            const messageTemplateSettings = {
                method: 'POST',
                headers: {
                    'Authorization': API_KEY,
                    'Content-Type': 'application/json',
                    'Accept': 'application/json'
                },
                body: JSON.stringify({
                    pinType: 'NUMERIC',
                    messageText: 'Your pin is {{pin}}',
                    pinLength: 4,
                    language: 'en',
                    senderId: 'Infobip 2FA',
                    repeatDTMF: '1#',
                    speechRate: 1
                })
            };

            const messageTemplateResponse = await fetch(API_2FA_BASE_URL + `${applicationId}/messages`, messageTemplateSettings);
            const messageTemplateData = await messageTemplateResponse.json();
            const messageId = messageTemplateData.id;
            console.log(`Message ID: ${messageId}`);

            const sendPINSettings = {
                method: 'POST',
                headers: {
                    'Authorization': API_KEY,
                    'Content-Type': 'application/json',
                    'Accept': 'application/json'
                },
                body: JSON.stringify({
                    applicationId: applicationId,
                    messageId: messageId,
                    from: 'InfoBib SMS TEST PIN :0',
                    to: '<phone Number here>',
                    placeholders: {
                        firstName: 'LISA'
                    }
                })
            };

            const sendPinResponse = await fetch(API_PIN_URL + '?ncNeeded=false', sendPINSettings);
            const sendPinData = await sendPinResponse.json();
            console.log(sendPinData);

            res.status(200).json(newUser);
        }
    } catch (error) {
        res.status(400).send(error.message);
    }
});

router.post("/test/sendSMS", async (req, res) => {
    const phoneNumber = '<>';
    try {
        console.log("Test");
        const configuration = {
            basePath: process.env.API_BASE_URL,
            apiKeyPrefix: 'App',
            apiKey: process.env.API_KEY
        };
        const smsMessage = {
            from: SENDER,
            destinations: [{ to: phoneNumber }],
            text: MESSAGE_TEXT
        };
        const smsRequest = {
            messages: [smsMessage]
        };

        const response = await fetch(`${process.env.API_BASE_URL}/sms/1/text/advanced`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `App ${process.env.API_KEY}`
            },
            body: JSON.stringify(smsRequest)
        });

        const data = await response.json();

        res.json({ response: data.messages[0] });
    } catch (error) {
        res.status(500).json({ error: error.message });
        console.log('Not Working :(');
    }
});

module.exports = router;

I don't know what the issue is. I'd really appreciate it if anyone could help!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Lisa
  • 53
  • 1
  • 10

0 Answers0