mirror of
https://github.com/kremalicious/umami.git
synced 2024-12-18 07:13:37 +01:00
Merge branch 'master' into dev
This commit is contained in:
commit
0bf8b23662
@ -22,6 +22,12 @@ export default function LanguageButton() {
|
|||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{locale === 'zh-TW' && (
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{locale === 'ja-JP' && (
|
{locale === 'ja-JP' && (
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&display=swap"
|
||||||
|
99
lang/zh-TW.json
Normal file
99
lang/zh-TW.json
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
{
|
||||||
|
"label.accounts": "帳戶",
|
||||||
|
"label.add-account": "增加帳戶",
|
||||||
|
"label.add-website": "增加網站",
|
||||||
|
"label.administrator": "管理員",
|
||||||
|
"label.all": "所有",
|
||||||
|
"label.all-websites": "全部網站",
|
||||||
|
"label.back": "返回",
|
||||||
|
"label.cancel": "取消",
|
||||||
|
"label.change-password": "更新密碼",
|
||||||
|
"label.confirm-password": "確認密碼",
|
||||||
|
"label.copy-to-clipboard": "複製",
|
||||||
|
"label.current-password": "目前密碼",
|
||||||
|
"label.custom-range": "自定義時段",
|
||||||
|
"label.dashboard": "管理面板",
|
||||||
|
"label.date-range": "多日",
|
||||||
|
"label.default-date-range": "默認日期範圍",
|
||||||
|
"label.delete": "刪除",
|
||||||
|
"label.delete-account": "刪除帳戶",
|
||||||
|
"label.delete-website": "删除網站",
|
||||||
|
"label.dismiss": "關閉",
|
||||||
|
"label.domain": "域名",
|
||||||
|
"label.edit": "編輯",
|
||||||
|
"label.edit-account": "編輯帳戶",
|
||||||
|
"label.edit-website": "編輯網站",
|
||||||
|
"label.enable-share-url": "啟用分享連結",
|
||||||
|
"label.invalid": "無效輸入",
|
||||||
|
"label.invalid-domain": "無效域名",
|
||||||
|
"label.last-days": "最近 {x} 天",
|
||||||
|
"label.last-hours": "最近 {x} 小時",
|
||||||
|
"label.logged-in-as": "用戶名: {username}",
|
||||||
|
"label.login": "登入",
|
||||||
|
"label.logout": "退出",
|
||||||
|
"label.more": "更多",
|
||||||
|
"label.name": "名字",
|
||||||
|
"label.new-password": "新密碼",
|
||||||
|
"label.password": "密碼",
|
||||||
|
"label.passwords-dont-match": "密碼不一致",
|
||||||
|
"label.profile": "個人資料",
|
||||||
|
"label.realtime": "實時",
|
||||||
|
"label.realtime-logs": "實時日志",
|
||||||
|
"label.refresh": "刷新",
|
||||||
|
"label.required": "必填",
|
||||||
|
"label.reset": "重置",
|
||||||
|
"label.save": "保存",
|
||||||
|
"label.settings": "設置",
|
||||||
|
"label.share-url": "分享連結",
|
||||||
|
"label.single-day": "單日",
|
||||||
|
"label.this-month": "本月",
|
||||||
|
"label.this-week": "本週",
|
||||||
|
"label.this-year": "今年",
|
||||||
|
"label.timezone": "時區",
|
||||||
|
"label.today": "今天",
|
||||||
|
"label.tracking-code": "追蹤代碼",
|
||||||
|
"label.unknown": "未知",
|
||||||
|
"label.username": "用户名",
|
||||||
|
"label.view-details": "查看更多",
|
||||||
|
"label.websites": "網站",
|
||||||
|
"message.active-users": "当前線上 {x} 人",
|
||||||
|
"message.confirm-delete": "你確定要删除{target}嗎?",
|
||||||
|
"message.copied": "複製成功!",
|
||||||
|
"message.delete-warning": "所有相關數據將會被删除.",
|
||||||
|
"message.failure": "出現錯誤.",
|
||||||
|
"message.get-share-url": "獲得分享連結",
|
||||||
|
"message.get-tracking-code": "獲得追蹤代碼",
|
||||||
|
"message.go-to-settings": "去設定",
|
||||||
|
"message.incorrect-username-password": "用户名或密碼不正確.",
|
||||||
|
"message.log.visitor": "自 {country} 的訪客在搭載 {os} 的 {device} 上使用 {browser} 進行訪問.",
|
||||||
|
"message.new-version-available": "umami 有新版本 {version} 發佈啦!",
|
||||||
|
"message.no-data-available": "無可用數據.",
|
||||||
|
"message.no-websites-configured": "目前無任何網站設定.",
|
||||||
|
"message.page-not-found": "網頁未找到.",
|
||||||
|
"message.powered-by": "運行 {name}",
|
||||||
|
"message.save-success": "成功保存.",
|
||||||
|
"message.share-url": "這是 {target} 的分享連結.",
|
||||||
|
"message.track-stats": "將以下代碼放入被設定網站的{head}部分来收集{target}的資料.",
|
||||||
|
"message.type-delete": "在下方空格輸入{delete}確認",
|
||||||
|
"metrics.actions": "用戶行為",
|
||||||
|
"metrics.average-visit-time": "平均訪問時間",
|
||||||
|
"metrics.bounce-rate": "跳出率",
|
||||||
|
"metrics.browsers": "瀏覽器",
|
||||||
|
"metrics.countries": "國家",
|
||||||
|
"metrics.device.desktop": "桌機",
|
||||||
|
"metrics.device.laptop": "筆記本",
|
||||||
|
"metrics.device.mobile": "手機",
|
||||||
|
"metrics.device.tablet": "平板",
|
||||||
|
"metrics.devices": "裝置",
|
||||||
|
"metrics.events": "行為類別",
|
||||||
|
"metrics.filter.combined": "總和",
|
||||||
|
"metrics.filter.domain-only": "僅域名",
|
||||||
|
"metrics.filter.raw": "原始",
|
||||||
|
"metrics.operating-systems": "操作系统",
|
||||||
|
"metrics.page-views": "網頁流量",
|
||||||
|
"metrics.pages": "網頁",
|
||||||
|
"metrics.referrers": "指入域名",
|
||||||
|
"metrics.unique-visitors": "獨立訪客",
|
||||||
|
"metrics.views": "页面流量",
|
||||||
|
"metrics.visitors": "獨立訪客"
|
||||||
|
}
|
@ -3,6 +3,7 @@ import {
|
|||||||
enUS,
|
enUS,
|
||||||
nl,
|
nl,
|
||||||
zhCN,
|
zhCN,
|
||||||
|
zhTW,
|
||||||
tr,
|
tr,
|
||||||
ru,
|
ru,
|
||||||
de,
|
de,
|
||||||
@ -22,6 +23,7 @@ import {
|
|||||||
import enMessages from 'lang-compiled/en-US.json';
|
import enMessages from 'lang-compiled/en-US.json';
|
||||||
import nlMessages from 'lang-compiled/nl-NL.json';
|
import nlMessages from 'lang-compiled/nl-NL.json';
|
||||||
import zhCNMessages from 'lang-compiled/zh-CN.json';
|
import zhCNMessages from 'lang-compiled/zh-CN.json';
|
||||||
|
import zhTWMessages from 'lang-compiled/zh-TW.json';
|
||||||
import trTRMessages from 'lang-compiled/tr-TR.json';
|
import trTRMessages from 'lang-compiled/tr-TR.json';
|
||||||
import ruRUMessages from 'lang-compiled/ru-RU.json';
|
import ruRUMessages from 'lang-compiled/ru-RU.json';
|
||||||
import deDEMessages from 'lang-compiled/de-DE.json';
|
import deDEMessages from 'lang-compiled/de-DE.json';
|
||||||
@ -44,6 +46,7 @@ export const messages = {
|
|||||||
'en-US': enMessages,
|
'en-US': enMessages,
|
||||||
'nl-NL': nlMessages,
|
'nl-NL': nlMessages,
|
||||||
'zh-CN': zhCNMessages,
|
'zh-CN': zhCNMessages,
|
||||||
|
'zh-TW': zhTWMessages,
|
||||||
'de-DE': deDEMessages,
|
'de-DE': deDEMessages,
|
||||||
'ru-RU': ruRUMessages,
|
'ru-RU': ruRUMessages,
|
||||||
'tr-TR': trTRMessages,
|
'tr-TR': trTRMessages,
|
||||||
@ -67,6 +70,7 @@ export const dateLocales = {
|
|||||||
'en-US': enUS,
|
'en-US': enUS,
|
||||||
'nl-NL': nl,
|
'nl-NL': nl,
|
||||||
'zh-CN': zhCN,
|
'zh-CN': zhCN,
|
||||||
|
'zh-TW': zhTW,
|
||||||
'de-DE': de,
|
'de-DE': de,
|
||||||
'da-DK': da,
|
'da-DK': da,
|
||||||
'ru-RU': ru,
|
'ru-RU': ru,
|
||||||
@ -88,6 +92,7 @@ export const dateLocales = {
|
|||||||
|
|
||||||
export const menuOptions = [
|
export const menuOptions = [
|
||||||
{ label: '中文', value: 'zh-CN', display: 'cn' },
|
{ label: '中文', value: 'zh-CN', display: 'cn' },
|
||||||
|
{ label: '中文(繁體)', value: 'zh-TW', display: 'tw' },
|
||||||
{ label: 'Dansk', value: 'da-DK', display: 'da' },
|
{ label: 'Dansk', value: 'da-DK', display: 'da' },
|
||||||
{ label: 'Deutsch', value: 'de-DE', display: 'de' },
|
{ label: 'Deutsch', value: 'de-DE', display: 'de' },
|
||||||
{ label: 'English', value: 'en-US', display: 'en' },
|
{ label: 'English', value: 'en-US', display: 'en' },
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"maxmind": "^4.3.0",
|
"maxmind": "^4.3.0",
|
||||||
"moment-timezone": "^0.5.31",
|
"moment-timezone": "^0.5.31",
|
||||||
"next": "^9.5.5",
|
"next": "^9.5.5",
|
||||||
|
"prompts": "2.3.2",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-intl": "^5.8.4",
|
"react-intl": "^5.8.4",
|
||||||
|
98
scripts/change-password.js
Normal file
98
scripts/change-password.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
require('dotenv').config();
|
||||||
|
const bcrypt = require('bcrypt');
|
||||||
|
const chalk = require('chalk');
|
||||||
|
const prompts = require('prompts');
|
||||||
|
const { PrismaClient } = require('@prisma/client');
|
||||||
|
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
const SALT_ROUNDS = 10;
|
||||||
|
|
||||||
|
const runQuery = async query => {
|
||||||
|
return query.catch(e => {
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateAccountByUsername = (username, data) => {
|
||||||
|
return runQuery(
|
||||||
|
prisma.account.update({
|
||||||
|
where: {
|
||||||
|
username,
|
||||||
|
},
|
||||||
|
data,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const hashPassword = password => {
|
||||||
|
return bcrypt.hash(password, SALT_ROUNDS);
|
||||||
|
};
|
||||||
|
|
||||||
|
const changePassword = async (username, newPassword) => {
|
||||||
|
const password = await hashPassword(newPassword);
|
||||||
|
return updateAccountByUsername(username, { password });
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUsernameAndPassword = async () => {
|
||||||
|
let [username, password] = process.argv.slice(2);
|
||||||
|
if (username && password) {
|
||||||
|
return { username, password };
|
||||||
|
}
|
||||||
|
|
||||||
|
const questions = [];
|
||||||
|
if (!username) {
|
||||||
|
questions.push({
|
||||||
|
type: 'text',
|
||||||
|
name: 'username',
|
||||||
|
message: 'Enter account to change password',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!password) {
|
||||||
|
questions.push(
|
||||||
|
{
|
||||||
|
type: 'password',
|
||||||
|
name: 'password',
|
||||||
|
message: 'Enter new password',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'password',
|
||||||
|
name: 'confirmation',
|
||||||
|
message: 'Confirm new password',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const answers = await prompts(questions);
|
||||||
|
if (answers.password !== answers.confirmation) {
|
||||||
|
throw new Error(`Passwords don't match`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
username: username || answers.username,
|
||||||
|
password: answers.password,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
let username, password;
|
||||||
|
|
||||||
|
try {
|
||||||
|
({ username, password } = await getUsernameAndPassword());
|
||||||
|
} catch (error) {
|
||||||
|
console.log(chalk.redBright(error.message));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await changePassword(username, password);
|
||||||
|
console.log('Password changed for user', chalk.greenBright(username));
|
||||||
|
} catch (error) {
|
||||||
|
if (error.message.includes('RecordNotFound')) {
|
||||||
|
console.log('Account not found:', chalk.redBright(username));
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prisma.$disconnect();
|
||||||
|
})();
|
@ -2,6 +2,7 @@
|
|||||||
"de-DE": [
|
"de-DE": [
|
||||||
"label.administrator",
|
"label.administrator",
|
||||||
"label.name",
|
"label.name",
|
||||||
|
"label.domain",
|
||||||
"metrics.device.desktop",
|
"metrics.device.desktop",
|
||||||
"metrics.device.laptop",
|
"metrics.device.laptop",
|
||||||
"metrics.device.tablet",
|
"metrics.device.tablet",
|
||||||
|
18
yarn.lock
18
yarn.lock
@ -5281,6 +5281,11 @@ kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
|
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
|
||||||
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
|
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
|
||||||
|
|
||||||
|
kleur@^3.0.3:
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
|
||||||
|
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
|
||||||
|
|
||||||
klona@^2.0.3:
|
klona@^2.0.3:
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0"
|
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0"
|
||||||
@ -7187,6 +7192,14 @@ promise-inflight@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
||||||
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
|
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
|
||||||
|
|
||||||
|
prompts@2.3.2:
|
||||||
|
version "2.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068"
|
||||||
|
integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==
|
||||||
|
dependencies:
|
||||||
|
kleur "^3.0.3"
|
||||||
|
sisteransi "^1.0.4"
|
||||||
|
|
||||||
prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2:
|
prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||||
version "15.7.2"
|
version "15.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||||
@ -8028,6 +8041,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||||
|
|
||||||
|
sisteransi@^1.0.4:
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
|
||||||
|
integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
|
||||||
|
|
||||||
slash@^3.0.0:
|
slash@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||||
|
Loading…
Reference in New Issue
Block a user