Await допустимо только в асинхронных функциях и телах модулей верхнего уровня javascript express error

Этот код предназначен для проверки аутентификации Firebase. Во-первых, он проверяет req.headers. Затем извлекает uid из токена. После получения decodedToken.uid код сверится со своей собственной базой данных MySQL, чтобы получить идентификатор пользователя с помощью функции getID(uid). Если uid отсутствует в базе, он создаст нового пользователя с помощью функции makeNewUser(). При выполнении код возвращает ошибку «ожидание допустимо только в асинхронных функциях и телах модулей верхнего уровня». Как я могу это исправить? Должен ли я создать новый файл для обработки этого материала, а возврат этого кода должен храниться в res.locals? Вот код.


const admin = require('./config/firebaseAuth'); // import admin from firebase initializeApp
const getId = require('../utils/getUserID'); // module to get userId form MySQL database
const makeNewUser = require('../utils/makeNewUser'); // module to make a new user into MySQL database


class Middleware {
    async decodeToken(req,res,next) {
        // get authorization from the headers
        const { authorization } = req.headers; 

        // check if the authorization headers are well configured
        // this includes checking if headers.authorization exist
        // then if the format in headers.authorization matches with the configured
        if (!authorization) return res.status(403).json({
            status: 'fail', 
            type: 'server/missing-authorization',
            message: 'Missing req.headers.authorization on request to the server. This is need for authorization!'
        })

        else if (!authorization.startWith('Bearer')) return res.status(400).json({
            status: 'fail', 
            type: 'server/missing-bearer',
            message: 'Missing Bearer in req.headers.authorization on request to the server. This is needed to extract the token!'
        })

        else if (authorization.split(' ').length !== 2) return res.status(400).json({
            status: 'fail',
            type: 'server/bearer-unrecognized',
            message: 'Bearer in req.headers.authorization is not well configured. This is need to extract the token!'
        })
        // after passing the authorization header checks, now checks the token
        const token = authorization.split(' ')[1]; // req.headers = {"Bearer $.token"} 
        admin.auth().verifyIdToken(token)
            .then((decodedToken) => {
                const {uid, name} = decodedToken; // get uid and name from the token
                try {
                    // !this produces an error: await is only valid in async functions and the top level bodies of modules
                    const result = await getId(uid); // getId to get the id of the user regarding the uid
                    // check if exist uid in the database
                    if (result.length < 1) {
                        // if not make a new user
                        const result = await makeNewUser(uid, name); // make new user from the given uid and name
                        const id = result.insertId; // get the id of the new user
                        req.user = {id: id, name: name}; // set id and name to req.user
                        return next();
                    }
                    const id = result[0].id; // getId to get the id of the user from the result query since uid exist
                    req.user = {id: id, name: name}; // set id and name to req.user 
                    return next();
                } catch (err) {
                    return res.status(500).json({
                        status: 'fail',
                        type: 'database/fail-to-query',
                        message: err.message
                    })
                }
            })
            .catch((err) => {
                /*
                on err for firebase tokens, such as sent was FMC token instead of id token or token has expired and many others!
                err response: after executing console.info(err)
                {
                    errorInfo: {
                    code: 'auth/argument-error',
                    message: 'Decoding Firebase ID token failed. Make sure you passed the entire string JWT which represents an ID token. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.'
                    },
                    codePrefix: 'auth'
                }
                or
                {
                    errorInfo: {
                        code: 'auth/id-token-expired',
                        message: 'Firebase ID token has expired. Get a fresh ID token from your client app and try again (auth/id-token-expired). See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.'
                    },
                    codePrefix: 'auth'
                }
                */
                if (err.errorInfo.code === 'auth/internal-error') var statusCode = 500;
                else var statusCode = 400; 
                return res.status(statusCode).json({status: "fail", type: err.errorInfo.code, message: err.errorInfo.message}); // return with status codes
            })
    }
}

module.exports = new Middleware();

Примечания: getId и makeNewUser возвращают обещание!

🤔 А знаете ли вы, что...
JavaScript был первоначально создан для улучшения интерактивности веб-страниц.


1
28
1

Ответ:

Решено

использовать это

const admin = require('./config/firebaseAuth'); // import admin from firebase initializeApp
    const getId = require('../utils/getUserID'); // module to get userId form MySQL database
    const makeNewUser = require('../utils/makeNewUser'); // module to make a new user into MySQL database
    
    
    class Middleware {
        async decodeToken(req,res,next) {
            // get authorization from the headers
            const { authorization } = req.headers; 
    
            // check if the authorization headers are well configured
            // this includes checking if headers.authorization exist
            // then if the format in headers.authorization matches with the configured
            if (!authorization) return res.status(403).json({
                status: 'fail', 
                type: 'server/missing-authorization',
                message: 'Missing req.headers.authorization on request to the server. This is need for authorization!'
            })
    
            else if (!authorization.startWith('Bearer')) return res.status(400).json({
                status: 'fail', 
                type: 'server/missing-bearer',
                message: 'Missing Bearer in req.headers.authorization on request to the server. This is needed to extract the token!'
            })
    
            else if (authorization.split(' ').length !== 2) return res.status(400).json({
                status: 'fail',
                type: 'server/bearer-unrecognized',
                message: 'Bearer in req.headers.authorization is not well configured. This is need to extract the token!'
            })
            // after passing the authorization header checks, now checks the token
            const token = authorization.split(' ')[1]; // req.headers = {"Bearer $.token"} 
            admin.auth().verifyIdToken(token)
                .then( async (decodedToken) => {
                    const {uid, name} = decodedToken; // get uid and name from the token
                    try {
                        // !this produces an error: await is only valid in async functions and the top level bodies of modules
                        const result = await getId(uid); // getId to get the id of the user regarding the uid
                        // check if exist uid in the database
                        if (result.length < 1) {
                            // if not make a new user
                            const result = await makeNewUser(uid, name); // make new user from the given uid and name
                            const id = result.insertId; // get the id of the new user
                            req.user = {id: id, name: name}; // set id and name to req.user
                            return next();
                        }
                        const id = result[0].id; // getId to get the id of the user from the result query since uid exist
                        req.user = {id: id, name: name}; // set id and name to req.user 
                        return next();
                    } catch (err) {
                        return res.status(500).json({
                            status: 'fail',
                            type: 'database/fail-to-query',
                            message: err.message
                        })
                    }
                })
                .catch((err) => {
                    /*
                    on err for firebase tokens, such as sent was FMC token instead of id token or token has expired and many others!
                    err response: after executing console.info(err)
                    {
                        errorInfo: {
                        code: 'auth/argument-error',
                        message: 'Decoding Firebase ID token failed. Make sure you passed the entire string JWT which represents an ID token. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.'
                        },
                        codePrefix: 'auth'
                    }
                    or
                    {
                        errorInfo: {
                            code: 'auth/id-token-expired',
                            message: 'Firebase ID token has expired. Get a fresh ID token from your client app and try again (auth/id-token-expired). See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.'
                        },
                        codePrefix: 'auth'
                    }
                    */
                    if (err.errorInfo.code === 'auth/internal-error') var statusCode = 500;
                    else var statusCode = 400; 
                    return res.status(statusCode).json({status: "fail", type: err.errorInfo.code, message: err.errorInfo.message}); // return with status codes
                })
        }
    }
    
    module.exports = new Middleware();