juice-shop
74 строки · 3.1 Кб
1/*
2* Copyright (c) 2014-2024 Bjoern Kimminich & the OWASP Juice Shop contributors.
3* SPDX-License-Identifier: MIT
4*/
5
6import locales from '../data/static/locales.json'
7import fs = require('fs')
8import { type Request, type Response, type NextFunction } from 'express'
9
10module.exports = function getLanguageList () { // TODO Refactor and extend to also load backend translations from /i18n/*json and calculate joint percentage/gauge
11return (req: Request, res: Response, next: NextFunction) => {
12const languages: Array<{ key: string, lang: any, icons: string[], shortKey: string, percentage: unknown, gauge: string }> = []
13let count = 0
14let enContent: any
15
16fs.readFile('frontend/dist/frontend/assets/i18n/en.json', 'utf-8', (err, content) => {
17if (err != null) {
18next(new Error(`Unable to retrieve en.json language file: ${err.message}`))
19}
20enContent = JSON.parse(content)
21fs.readdir('frontend/dist/frontend/assets/i18n/', (err, languageFiles) => {
22if (err != null) {
23next(new Error(`Unable to read i18n directory: ${err.message}`))
24}
25languageFiles.forEach((fileName) => {
26// eslint-disable-next-line @typescript-eslint/no-misused-promises
27fs.readFile('frontend/dist/frontend/assets/i18n/' + fileName, 'utf-8', async (err, content) => {
28if (err != null) {
29next(new Error(`Unable to retrieve ${fileName} language file: ${err.message}`))
30}
31const fileContent = JSON.parse(content)
32const percentage = await calcPercentage(fileContent, enContent)
33const key = fileName.substring(0, fileName.indexOf('.'))
34const locale = locales.find((l) => l.key === key)
35const lang: any = {
36key,
37lang: fileContent.LANGUAGE,
38icons: locale?.icons,
39shortKey: locale?.shortKey,
40percentage,
41gauge: (percentage > 90 ? 'full' : (percentage > 70 ? 'three-quarters' : (percentage > 50 ? 'half' : (percentage > 30 ? 'quarter' : 'empty'))))
42}
43if (!(fileName === 'en.json' || fileName === 'tlh_AA.json')) {
44languages.push(lang)
45}
46count++
47if (count === languageFiles.length) {
48languages.push({ key: 'en', icons: ['gb', 'us'], shortKey: 'EN', lang: 'English', percentage: 100, gauge: 'full' })
49languages.sort((a, b) => a.lang.localeCompare(b.lang))
50res.status(200).json(languages)
51}
52})
53})
54})
55})
56
57async function calcPercentage (fileContent: any, enContent: any): Promise<number> {
58const totalStrings = Object.keys(enContent).length
59let differentStrings = 0
60return await new Promise((resolve, reject) => {
61try {
62for (const key in fileContent) {
63if (Object.prototype.hasOwnProperty.call(fileContent, key) && fileContent[key] !== enContent[key]) {
64differentStrings++
65}
66}
67resolve((differentStrings / totalStrings) * 100)
68} catch (err) {
69reject(err)
70}
71})
72}
73}
74}
75