"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.tokensRouter = void 0;
const tslib_1 = require("tslib");
const express_1 = tslib_1.__importDefault(require("express"));
const logger_1 = require("../../../helpers/logger");
const config_1 = require("../../../initializers/config");
const constants_1 = require("../../../initializers/constants");
const external_auth_1 = require("../../../lib/auth/external-auth");
const oauth_1 = require("../../../lib/auth/oauth");
const oauth_model_1 = require("../../../lib/auth/oauth-model");
const hooks_1 = require("../../../lib/plugins/hooks");
const middlewares_1 = require("../../../middlewares");
const extra_utils_1 = require("../../../../shared/extra-utils");
const tokensRouter = express_1.default.Router();
exports.tokensRouter = tokensRouter;
const loginRateLimiter = (0, middlewares_1.buildRateLimiter)({
    windowMs: config_1.CONFIG.RATES_LIMIT.LOGIN.WINDOW_MS,
    max: config_1.CONFIG.RATES_LIMIT.LOGIN.MAX
});
tokensRouter.post('/token', loginRateLimiter, (0, middlewares_1.openapiOperationDoc)({ operationId: 'getOAuthToken' }), (0, middlewares_1.asyncMiddleware)(handleToken));
tokensRouter.post('/revoke-token', (0, middlewares_1.openapiOperationDoc)({ operationId: 'revokeOAuthToken' }), middlewares_1.authenticate, (0, middlewares_1.asyncMiddleware)(handleTokenRevocation));
tokensRouter.get('/scoped-tokens', middlewares_1.authenticate, getScopedTokens);
tokensRouter.post('/scoped-tokens', middlewares_1.authenticate, (0, middlewares_1.asyncMiddleware)(renewScopedTokens));
function handleToken(req, res, next) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const grantType = req.body.grant_type;
        try {
            const bypassLogin = yield buildByPassLogin(req, grantType);
            const refreshTokenAuthName = grantType === 'refresh_token'
                ? yield (0, external_auth_1.getAuthNameFromRefreshGrant)(req.body.refresh_token)
                : undefined;
            const options = {
                refreshTokenAuthName,
                bypassLogin
            };
            const token = yield (0, oauth_1.handleOAuthToken)(req, options);
            res.set('Cache-Control', 'no-store');
            res.set('Pragma', 'no-cache');
            hooks_1.Hooks.runAction('action:api.user.oauth2-got-token', { username: token.user.username, ip: req.ip, req, res });
            return res.json({
                token_type: 'Bearer',
                access_token: token.accessToken,
                refresh_token: token.refreshToken,
                expires_in: token.accessTokenExpiresIn,
                refresh_token_expires_in: token.refreshTokenExpiresIn
            });
        }
        catch (err) {
            logger_1.logger.warn('Login error', { err });
            if (err instanceof oauth_1.MissingTwoFactorError) {
                res.set(constants_1.OTP.HEADER_NAME, constants_1.OTP.HEADER_REQUIRED_VALUE);
            }
            return res.fail({
                status: err.code,
                message: err.message,
                type: err.name
            });
        }
    });
}
function handleTokenRevocation(req, res) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const token = res.locals.oauth.token;
        const result = yield (0, oauth_model_1.revokeToken)(token, { req, explicitLogout: true });
        return res.json(result);
    });
}
function getScopedTokens(req, res) {
    const user = res.locals.oauth.token.user;
    return res.json({
        feedToken: user.feedToken
    });
}
function renewScopedTokens(req, res) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        const user = res.locals.oauth.token.user;
        user.feedToken = (0, extra_utils_1.buildUUID)();
        yield user.save();
        return res.json({
            feedToken: user.feedToken
        });
    });
}
function buildByPassLogin(req, grantType) {
    return tslib_1.__awaiter(this, void 0, void 0, function* () {
        if (grantType !== 'password')
            return undefined;
        if (req.body.externalAuthToken) {
            return (0, external_auth_1.getBypassFromExternalAuth)(req.body.username, req.body.externalAuthToken);
        }
        return (0, external_auth_1.getBypassFromPasswordGrant)(req.body.username, req.body.password);
    });
}
//# sourceMappingURL=token.js.map