@crowdin/app-project-module
Version:
Module that generates for you all common endpoints for serving standalone Crowdin App
181 lines (180 loc) • 6.95 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFormattedDate = exports.validateEmail = exports.prepareFormDataMetadataId = exports.getPreviousDate = exports.isJson = exports.isAuthorizedConfig = exports.getLogoUrl = exports.executeWithRetry = exports.decryptData = exports.encryptData = exports.runAsyncWrapper = exports.CodeError = void 0;
const crypto = __importStar(require("crypto-js"));
const storage_1 = require("../storage");
const types_1 = require("../types");
const logger_1 = require("./logger");
const crowdin_apps_functions_1 = require("@crowdin/crowdin-apps-functions");
class CodeError extends Error {
constructor(message, code) {
super(message);
this.code = code;
}
}
exports.CodeError = CodeError;
function isCrowdinClientRequest(req) {
return req.crowdinContext;
}
function handleError(err, req, res) {
return __awaiter(this, void 0, void 0, function* () {
const code = err.code && typeof err.code === 'number' ? err.code : 500;
if (code === 401 && isCrowdinClientRequest(req)) {
yield (0, storage_1.getStorage)().deleteIntegrationCredentials(req.crowdinContext.clientId);
}
if (code === 401 && req.path === '/') {
res.redirect('/');
return;
}
if (!res.headersSent) {
const errorMessage = { message: (0, logger_1.getErrorMessage)(err), code };
if ('integrationCredentials' in req) {
res.render('error', errorMessage);
}
else {
res.status(code).send(errorMessage);
}
}
});
}
function runAsyncWrapper(callback) {
return (req, res, next) => {
callback(req, res, next).catch((e) => {
if (isCrowdinClientRequest(req)) {
req.logError(e);
}
else {
(0, logger_1.logError)(e);
}
handleError(e, req, res);
});
};
}
exports.runAsyncWrapper = runAsyncWrapper;
function encryptData(config, data) {
return crypto.AES.encrypt(data, config.cryptoSecret || config.clientSecret).toString();
}
exports.encryptData = encryptData;
function decryptData(config, data) {
return crypto.AES.decrypt(data, config.cryptoSecret || config.clientSecret).toString(crypto.enc.Utf8);
}
exports.decryptData = decryptData;
function executeWithRetry(func, numOfRetries = 2) {
return __awaiter(this, void 0, void 0, function* () {
for (let i = 0; i <= numOfRetries; i++) {
try {
const result = yield func();
return result;
}
catch (error) {
if (i === numOfRetries) {
throw error;
}
}
}
throw new Error('Failed to process request with retry');
});
}
exports.executeWithRetry = executeWithRetry;
function getLogoUrl(moduleConfig, modulePath) {
if (!moduleConfig && !modulePath) {
return '/logo.png';
}
return `/logo${modulePath}/logo.png`;
}
exports.getLogoUrl = getLogoUrl;
function isAuthorizedConfig(config) {
return !!config.clientId && !!config.clientSecret && config.authenticationType !== types_1.AuthenticationType.NONE;
}
exports.isAuthorizedConfig = isAuthorizedConfig;
function isJson(string) {
try {
JSON.parse(string);
}
catch (e) {
return false;
}
return true;
}
exports.isJson = isJson;
function getPreviousDate(days) {
const date = new Date();
date.setDate(date.getDate() - days);
return date;
}
exports.getPreviousDate = getPreviousDate;
function prepareFormDataMetadataId(req, config) {
return __awaiter(this, void 0, void 0, function* () {
const jwtToken = req.query.jwtToken;
const jwtPayload = yield (0, crowdin_apps_functions_1.validateJwtToken)(jwtToken, config.clientSecret, config.jwtValidationOptions);
const context = jwtPayload.context;
const id = ['form-data'];
if (context.organization_id) {
id.push(`${context.organization_id}`);
}
if (context.project_id) {
id.push(`${context.project_id}`);
}
return id.join('-');
});
}
exports.prepareFormDataMetadataId = prepareFormDataMetadataId;
function validateEmail(email) {
if (!isNaN(+email)) {
return false;
}
if (`${email}`.trim().length > 76) {
return false;
}
const emailRegExp = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return emailRegExp.test(String(email).toLowerCase());
}
exports.validateEmail = validateEmail;
// Format the date as 'MMM DD, YYYY HH:mm'
function getFormattedDate({ date, userTimezone }) {
if (!userTimezone) {
userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
}
return new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: userTimezone,
}).format(date);
}
exports.getFormattedDate = getFormattedDate;