Merge remote-tracking branch 'remotes/origin/release/v1.0.0' into feature/api-descriptions

This commit is contained in:
Sergey Linnik 2023-04-20 12:11:10 +05:00
commit 2819a82c86
96 changed files with 1134 additions and 434 deletions

View File

@ -41,26 +41,6 @@ elif [ "$UPDATE" = "true" ] && [ "$DOCUMENT_SERVER_INSTALLED" = "true" ]; then
apt-get install -y --only-upgrade ${package_sysname}-documentserver apt-get install -y --only-upgrade ${package_sysname}-documentserver
fi fi
NGINX_ROOT_DIR="/etc/nginx"
NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-$(grep processor /proc/cpuinfo | wc -l)};
NGINX_WORKER_CONNECTIONS=${NGINX_WORKER_CONNECTIONS:-$(ulimit -n)};
sed 's/^worker_processes.*/'"worker_processes ${NGINX_WORKER_PROCESSES};"'/' -i ${NGINX_ROOT_DIR}/nginx.conf
sed 's/worker_connections.*/'"worker_connections ${NGINX_WORKER_CONNECTIONS};"'/' -i ${NGINX_ROOT_DIR}/nginx.conf
if ! id "nginx" &>/dev/null; then
systemctl stop nginx
rm -dfr /var/log/nginx/*
rm -dfr /var/cache/nginx/*
useradd -s /bin/false nginx
systemctl start nginx
else
systemctl reload nginx
fi
if [ "$PRODUCT_INSTALLED" = "false" ]; then if [ "$PRODUCT_INSTALLED" = "false" ]; then
echo ${product} ${product}/db-pwd select $MYSQL_SERVER_PASS | sudo debconf-set-selections echo ${product} ${product}/db-pwd select $MYSQL_SERVER_PASS | sudo debconf-set-selections
echo ${product} ${product}/db-user select $MYSQL_SERVER_USER | sudo debconf-set-selections echo ${product} ${product}/db-user select $MYSQL_SERVER_USER | sudo debconf-set-selections

View File

@ -118,14 +118,8 @@ apt-get install -o DPkg::options::="--force-confnew" -yq \
postgresql \ postgresql \
redis-server \ redis-server \
rabbitmq-server \ rabbitmq-server \
nginx-extras nginx-extras \
ffmpeg
if [ -e /etc/redis/redis.conf ]; then
sed -i "s/bind .*/bind 127.0.0.1/g" /etc/redis/redis.conf
sed -r "/^save\s[0-9]+/d" -i /etc/redis/redis.conf
service redis-server restart
fi
if [ ! -e /usr/bin/json ]; then if [ ! -e /usr/bin/json ]; then
npm i json -g >/dev/null 2>&1 npm i json -g >/dev/null 2>&1

View File

@ -10,13 +10,6 @@ cat<<EOF
EOF EOF
if [ -e /etc/redis.conf ]; then
sed -i "s/bind .*/bind 127.0.0.1/g" /etc/redis.conf
sed -r "/^save\s[0-9]+/d" -i /etc/redis.conf
systemctl restart redis
fi
sed "/host\s*all\s*all\s*127\.0\.0\.1\/32\s*ident$/s|ident$|trust|" -i /var/lib/pgsql/data/pg_hba.conf sed "/host\s*all\s*all\s*127\.0\.0\.1\/32\s*ident$/s|ident$|trust|" -i /var/lib/pgsql/data/pg_hba.conf
sed "/host\s*all\s*all\s*::1\/128\s*ident$/s|ident$|trust|" -i /var/lib/pgsql/data/pg_hba.conf sed "/host\s*all\s*all\s*::1\/128\s*ident$/s|ident$|trust|" -i /var/lib/pgsql/data/pg_hba.conf
@ -148,22 +141,6 @@ elif [[ $PRODUCT_CHECK_UPDATE -eq $UPDATE_AVAILABLE_CODE ]]; then
-mysqlp ${MYSQL_ROOT_PASS} -mysqlp ${MYSQL_ROOT_PASS}
fi fi
NGINX_ROOT_DIR="/etc/nginx"
NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-$(grep processor /proc/cpuinfo | wc -l)};
NGINX_WORKER_CONNECTIONS=${NGINX_WORKER_CONNECTIONS:-$(ulimit -n)};
sed 's/^worker_processes.*/'"worker_processes ${NGINX_WORKER_PROCESSES};"'/' -i ${NGINX_ROOT_DIR}/nginx.conf
sed 's/worker_connections.*/'"worker_connections ${NGINX_WORKER_CONNECTIONS};"'/' -i ${NGINX_ROOT_DIR}/nginx.conf
if rpm -q "firewalld"; then
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
systemctl restart firewalld.service
fi
systemctl restart nginx
echo "" echo ""
echo "$RES_INSTALL_SUCCESS" echo "$RES_INSTALL_SUCCESS"
echo "$RES_QUESTIONS" echo "$RES_QUESTIONS"

View File

@ -50,7 +50,6 @@ yum localinstall -y --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusi
MONOREV=$REV MONOREV=$REV
if [ "$REV" = "9" ]; then if [ "$REV" = "9" ]; then
MONOREV="8" MONOREV="8"
yum localinstall -y --nogpgcheck https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/xorg-x11-font-utils-7.5-41.el8.x86_64.rpm
elif [ "$REV" = "8" ]; then elif [ "$REV" = "8" ]; then
POWERTOOLS_REPO="--enablerepo=powertools" POWERTOOLS_REPO="--enablerepo=powertools"
fi fi
@ -61,6 +60,7 @@ curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.
#add nodejs repo #add nodejs repo
curl -sL https://rpm.nodesource.com/setup_16.x | sed 's/centos|/'$DIST'|/g' | sudo bash - || true curl -sL https://rpm.nodesource.com/setup_16.x | sed 's/centos|/'$DIST'|/g' | sudo bash - || true
rpm --import http://rpm.nodesource.com/pub/el/NODESOURCE-GPG-SIGNING-KEY-EL
#add dotnet repo #add dotnet repo
if [ $REV = "7" ] || [[ $DIST != "redhat" && $REV = "8" ]]; then if [ $REV = "7" ] || [[ $DIST != "redhat" && $REV = "8" ]]; then
@ -104,9 +104,6 @@ gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true module_hotfixes=true
END END
${package_manager} -y install python3-dnf-plugin-versionlock || ${package_manager} -y install yum-plugin-versionlock
${package_manager} versionlock clear
${package_manager} -y install epel-release \ ${package_manager} -y install epel-release \
python3 \ python3 \
nodejs \ nodejs \
@ -119,7 +116,8 @@ ${package_manager} -y install epel-release \
rabbitmq-server$rabbitmq_version \ rabbitmq-server$rabbitmq_version \
redis --enablerepo=remi \ redis --enablerepo=remi \
SDL2 $POWERTOOLS_REPO \ SDL2 $POWERTOOLS_REPO \
expect expect \
ffmpeg
py3_version=$(python3 -c 'import sys; print(sys.version_info.minor)') py3_version=$(python3 -c 'import sys; print(sys.version_info.minor)')
if [[ $py3_version -lt 6 ]]; then if [[ $py3_version -lt 6 ]]; then

View File

@ -420,6 +420,12 @@ setup_nginx(){
rm -f $NGINX_CONF/default.conf >/dev/null 2>&1 || rm -f $NGINX_DIR/sites-enabled/default >/dev/null 2>&1 rm -f $NGINX_CONF/default.conf >/dev/null 2>&1 || rm -f $NGINX_DIR/sites-enabled/default >/dev/null 2>&1
sed -i "s/listen.*;/listen $APP_PORT;/" $NGINX_CONF/${PACKAGE_SYSNAME}.conf sed -i "s/listen.*;/listen $APP_PORT;/" $NGINX_CONF/${PACKAGE_SYSNAME}.conf
NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-$(grep processor /proc/cpuinfo | wc -l)};
NGINX_WORKER_CONNECTIONS=${NGINX_WORKER_CONNECTIONS:-$(ulimit -n)};
sed "s!\(^worker_processes\).*;!\1 ${NGINX_WORKER_PROCESSES};!" -i ${NGINX_ROOT_DIR}/nginx.conf
sed "s!\(worker_connections\).*;!\1 ${NGINX_WORKER_CONNECTIONS};!" -i ${NGINX_ROOT_DIR}/nginx.conf
if [ "$DIST" = "RedHat" ]; then if [ "$DIST" = "RedHat" ]; then
# Remove default nginx settings # Remove default nginx settings
DELETION_LINE=$(sed -n '/server {/=' /etc/nginx/nginx.conf | head -n 1) DELETION_LINE=$(sed -n '/server {/=' /etc/nginx/nginx.conf | head -n 1)
@ -465,7 +471,26 @@ setup_nginx(){
true true
done done
fi fi
if rpm -q "firewalld"; then
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
systemctl restart firewalld.service
fi
elif [ "$DIST" = "Debian" ]; then
if ! id "nginx" &>/dev/null; then
systemctl stop nginx
rm -dfr /var/log/nginx/*
rm -dfr /var/cache/nginx/*
useradd -s /bin/false nginx
systemctl start nginx
else
systemctl reload nginx
fi
fi fi
chown nginx:nginx /etc/nginx/* -R chown nginx:nginx /etc/nginx/* -R
systemctl enable nginx >/dev/null 2>&1 systemctl enable nginx >/dev/null 2>&1
systemctl restart nginx systemctl restart nginx
@ -574,6 +599,11 @@ setup_redis() {
sed "s_\(\"Host\":\).*_\1 \"${REDIS_HOST}\",_" -i $APP_DIR/redis.json sed "s_\(\"Host\":\).*_\1 \"${REDIS_HOST}\",_" -i $APP_DIR/redis.json
sed "s_\(\"Port\":\).*_\1 \"${REDIS_PORT}\"_" -i $APP_DIR/redis.json sed "s_\(\"Port\":\).*_\1 \"${REDIS_PORT}\"_" -i $APP_DIR/redis.json
if [ -e /etc/redis/redis.conf ]; then
sed "s_\(^bind\).*_\1 ${REDIS_HOST}_" -i /etc/redis/redis.conf
sed -r "/^save\s[0-9]+/d" -i /etc/redis/redis.conf
fi
systemctl enable $REDIS_PACKAGE >/dev/null 2>&1 systemctl enable $REDIS_PACKAGE >/dev/null 2>&1
systemctl restart $REDIS_PACKAGE systemctl restart $REDIS_PACKAGE

View File

@ -63,6 +63,7 @@ Package: {{product}}-files-services
Architecture: any Architecture: any
Depends: {{product}}-common (= {{package_header_tag_version}}), Depends: {{product}}-common (= {{package_header_tag_version}}),
dotnet-sdk-7.0, dotnet-sdk-7.0,
ffmpeg,
${misc:Depends}, ${misc:Depends},
${shlibs:Depends} ${shlibs:Depends}
Description: {{product}}-files-services Description: {{product}}-files-services

View File

@ -18,7 +18,7 @@ Common
Summary: Files-services Summary: Files-services
Group: Applications/Internet Group: Applications/Internet
Requires: %name-common = %version-%release Requires: %name-common = %version-%release
Requires: dotnet-sdk-7.0 Requires: dotnet-sdk-7.0, ffmpeg
AutoReqProv: no AutoReqProv: no
%description files-services %description files-services
Files-services Files-services

View File

@ -1,7 +1,7 @@
/* /*
* *
* (c) Copyright Ascensio System Limited 2010-2021 * (c) Copyright Ascensio System Limited 2010-2023
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -12,141 +12,64 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
"use strict"; "use strict";
process.env.NODE_ENV = process.env.NODE_ENV || "development"; process.env.NODE_ENV = process.env.NODE_ENV || "development";
const fs = require("fs"), const http = require("http"),
http = require("http"), express = require("express"),
express = require("express"), morgan = require("morgan"),
morgan = require("morgan"), cookieParser = require("cookie-parser"),
cookieParser = require("cookie-parser"), bodyParser = require("body-parser"),
bodyParser = require("body-parser"), session = require("express-session"),
session = require("express-session"), winston = require("./app/log.js"),
winston = require("winston"), config = require("./config").get(),
WinstonCloudWatch = require('winston-cloudwatch'), path = require("path"),
config = require("./config").get(), exphbs = require("express-handlebars"),
path = require("path"), favicon = require("serve-favicon"),
exphbs = require("express-handlebars"), cors = require("cors");
favicon = require("serve-favicon"),
cors = require("cors"),
{ randomUUID } = require('crypto'),
date = require('date-and-time'),
os = require("os");
require('winston-daily-rotate-file'); winston.stream = {
write: (message) => winston.info(message),
};
const app = express(); const app = express();
let logpath = config["logPath"];
if(logpath != null)
{
if(!path.isAbsolute(logpath))
{
logpath = path.join(__dirname, logpath);
}
// ensure log directory exists
fs.existsSync(logpath) || fs.mkdirSync(logpath);
}
const aws = config["aws"].cloudWatch;
const accessKeyId = aws.accessKeyId;
const secretAccessKey = aws.secretAccessKey;
const awsRegion = aws.region;
const logGroupName = aws.logGroupName;
const logStreamName = aws.logStreamName.replace("${hostname}", os.hostname())
.replace("${applicationContext}", "SsoAuth")
.replace("${guid}", randomUUID())
.replace("${date}", date.format(new Date(), 'YYYY/MM/DDTHH.mm.ss'));
let transports = [];
if (config.logger.file) {
let logDir = logpath ? logpath : (config.app.logDir[0] === "." ? path.join(__dirname, config.app.logDir) : config.app.logDir);
config.logger.file.filename = path.join(logDir, config.app.logName);
transports.push(new (winston.transports.DailyRotateFile)(config.logger.file));
}
if (config.logger.console) {
transports.push(new (winston.transports.Console)(config.logger.console));
}
if (aws != null && aws.accessKeyId !== '')
{
transports.push(new WinstonCloudWatch({
name: 'aws',
level: "debug",
logStreamName: logStreamName,
logGroupName: logGroupName,
awsRegion: awsRegion,
jsonMessage: true,
awsOptions: {
credentials: {
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey
}
}
}));
}
const customFormat = winston.format(info => {
const now = new Date();
info.date = date.format(now, 'YYYY-MM-DD HH:mm:ss');
info.applicationContext = "SsoAuth";
info.level = info.level.toUpperCase();
const hostname = os.hostname();
info["instance-id"] = hostname;
return info;
})();
let logger = winston.createLogger({
format: winston.format.combine(
customFormat,
winston.format.json()
),
transports: transports,
exitOnError: false
});
logger.stream = {
write: function(message) {
logger.info(message.trim());
}
};
// view engine setup // view engine setup
app.set("views", path.join(__dirname, "views")); app.set("views", path.join(__dirname, "views"));
app.engine("handlebars", exphbs({ defaultLayout: "main" })); app.engine("handlebars", exphbs({ defaultLayout: "main" }));
app.set("view engine", "handlebars"); app.set("view engine", "handlebars");
app.use(favicon(path.join(__dirname, "public", "favicon.ico"))) const machineKey = config["core"].machinekey
.use(morgan("combined", { "stream": logger.stream })) ? config["core"].machinekey
.use(cookieParser()) : config.app.machinekey;
.use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: false }))
.use(session(
{
resave: true,
saveUninitialized: true,
secret: config["core"].machinekey ? config["core"].machinekey : config.app.machinekey
}))
.use(cors());
require("./app/middleware/saml")(app, config, logger); app
require("./app/routes")(app, config, logger); .use(favicon(path.join(__dirname, "public", "favicon.ico")))
.use(morgan("combined", { stream: winston.stream }))
.use(cookieParser())
.use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: false }))
.use(
session({
resave: true,
saveUninitialized: true,
secret: machineKey,
})
)
.use(cors());
require("./app/middleware/saml")(app, config);
require("./app/routes")(app, config);
const httpServer = http.createServer(app); const httpServer = http.createServer(app);
httpServer.listen(config.app.port, httpServer.listen(config.app.port, function () {
function () { winston.info(
logger.info(`Start SSO Service Provider listening on port ${config.app.port} for http`); `Start SSO Service Provider listening on port ${config.app.port} ` +
}); `machineKey='${machineKey}' ` +
`appsettings path='${config.app.appsettings}'`
);
});

View File

@ -0,0 +1,101 @@
const winston = require("winston"),
WinstonCloudWatch = require("winston-cloudwatch");
require("winston-daily-rotate-file");
const path = require("path");
const config = require("../config");
const fs = require("fs");
const os = require("os");
const { randomUUID } = require("crypto");
const date = require("date-and-time");
let logpath = config.get("logPath");
if (logpath != null) {
if (!path.isAbsolute(logpath)) {
logpath = path.join(__dirname, "..", logpath);
}
}
const fileName = logpath
? path.join(logpath, "web.sso.%DATE%.log")
: path.join(__dirname, "..", "..", "..", "Logs", "web.sso.%DATE%.log");
const dirName = path.dirname(fileName);
const aws = config.get("aws").cloudWatch;
const accessKeyId = aws.accessKeyId;
const secretAccessKey = aws.secretAccessKey;
const awsRegion = aws.region;
const logGroupName = aws.logGroupName;
const logStreamName = aws.logStreamName
.replace("${hostname}", os.hostname())
.replace("${applicationContext}", "SsoAuth")
.replace("${guid}", randomUUID())
.replace("${date}", date.format(new Date(), "YYYY/MM/DDTHH.mm.ss"));
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName);
}
var options = {
file: {
filename: fileName,
datePattern: "MM-DD",
handleExceptions: true,
humanReadableUnhandledException: true,
zippedArchive: true,
maxSize: "50m",
maxFiles: "30d",
json: true,
},
console: {
level: "debug",
handleExceptions: true,
json: false,
colorize: true,
},
cloudWatch: {
name: "aws",
level: "debug",
logStreamName: logStreamName,
logGroupName: logGroupName,
awsRegion: awsRegion,
jsonMessage: true,
awsOptions: {
credentials: {
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
},
},
},
};
let transports = [
new winston.transports.Console(options.console),
new winston.transports.DailyRotateFile(options.file),
];
if (aws != null && aws.accessKeyId !== "") {
transports.push(new WinstonCloudWatch(options.cloudWatch));
}
const customFormat = winston.format((info) => {
const now = new Date();
info.date = date.format(now, "YYYY-MM-DD HH:mm:ss");
info.applicationContext = "SsoAuth";
info.level = info.level.toUpperCase();
const hostname = os.hostname();
info["instance-id"] = hostname;
return info;
})();
module.exports = new winston.createLogger({
format: winston.format.combine(customFormat, winston.format.json()),
transports: transports,
exitOnError: false,
});

View File

@ -1,7 +1,7 @@
/* /*
* *
* (c) Copyright Ascensio System Limited 2010-2021 * (c) Copyright Ascensio System Limited 2010-2021
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -12,18 +12,21 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
"use strict"; "use strict";
module.exports = (app, config, logger) => { module.exports = (app, config) => {
const urlResolver = require("../utils/resolver")(logger); const logger = require("../log.js");
const urlResolver = require("../utils/resolver")();
const coder = require("../utils/coder"); const coder = require("../utils/coder");
const converter = require("../utils/converter")(logger); const converter = require("../utils/converter")();
const _ = require("lodash"); const _ = require("lodash");
const fetch = require("node-fetch"); const fetch = require("node-fetch");
const routes = _.values(config.routes); const routes = _.values(config.routes);
const machineKey = config["core"].machinekey
? config["core"].machinekey
: config.app.machinekey;
const fetchConfig = async (req, res, next) => { const fetchConfig = async (req, res, next) => {
const foundRoutes = const foundRoutes =
@ -33,9 +36,9 @@ module.exports = (app, config, logger) => {
}) })
: []; : [];
if(req.originalUrl =="/isLife") { if (req.originalUrl == "/isLife") {
res.sendStatus(200); res.sendStatus(200);
return; return;
} }
if (!foundRoutes.length) { if (!foundRoutes.length) {
@ -63,7 +66,7 @@ module.exports = (app, config, logger) => {
const text = await response.text(); const text = await response.text();
const ssoConfig = coder.decodeData(text); const ssoConfig = coder.decodeData(text, machineKey);
const idp = converter.toIdp(ssoConfig); const idp = converter.toIdp(ssoConfig);

View File

@ -17,10 +17,11 @@
"use strict"; "use strict";
module.exports = function (app, config, logger) { module.exports = function (app, config) {
const saml = require("samlify"); const saml = require("samlify");
const { SamlLib: libsaml } = saml; const { SamlLib: libsaml } = saml;
const urlResolver = require("./utils/resolver")(logger); const logger = require("./log.js");
const urlResolver = require("./utils/resolver")();
const coder = require("./utils/coder"); const coder = require("./utils/coder");
const urn = require("samlify/build/src/urn"); const urn = require("samlify/build/src/urn");
const fetch = require("node-fetch"); const fetch = require("node-fetch");
@ -32,8 +33,10 @@ module.exports = function (app, config, logger) {
const UserModel = require("./model/user"); const UserModel = require("./model/user");
const LogoutModel = require("./model/logout"); const LogoutModel = require("./model/logout");
const fs = require('fs'); const fs = require('fs');
let uploadDir = ""; let uploadDir = "";
const selfSignedDomain = "myselfsigned.crt"; const selfSignedDomain = "myselfsigned.crt";
const machineKey = config["core"].machinekey ? config["core"].machinekey : config.app.machinekey;
function verifySetting(req) { function verifySetting(req) {
if (!req.providersInfo.settings.EnableSso) { if (!req.providersInfo.settings.EnableSso) {
@ -396,13 +399,14 @@ module.exports = function (app, config, logger) {
req.providersInfo.mapping req.providersInfo.mapping
); );
logger.info(`SSO User ${JSON.stringify(user)}`); logger.info(`SSO User ${JSON.stringify(user)} machineKey=${machineKey}`);
// Use the parseResult can do customized action // Use the parseResult can do customized action
const data = coder.encodeData(user);
const data = coder.encodeData(user, machineKey);
if (!data) { if (!data) {
logger.error("coder.encodeData", user); logger.error("EncodeData response is EMPTY", user, machineKey);
return res.redirect( return res.redirect(
urlResolver.getPortalAuthErrorUrl( urlResolver.getPortalAuthErrorUrl(
req, req,
@ -511,10 +515,14 @@ module.exports = function (app, config, logger) {
const relayState = urlResolver.getPortalAuthUrl(req); const relayState = urlResolver.getPortalAuthUrl(req);
const userData = coder.decodeData(req.query["data"]); const queryData = req.query["data"];
logger.info(`sendLogoutRequest: data: ${queryData} machineKey=${machineKey}`);
const userData = coder.decodeData(queryData, machineKey);
if (!userData) { if (!userData) {
logger.error(`coder.decodeData ${req.query["data"]}`); logger.error("DecodeData response is EMPTY", queryData, machineKey);
return res.redirect(urlResolver.getPortal500Url(req)); return res.redirect(urlResolver.getPortal500Url(req));
} }
@ -599,11 +607,12 @@ module.exports = function (app, config, logger) {
const sendPortalLogout = async (user, req) => { const sendPortalLogout = async (user, req) => {
try { try {
const data = coder.encodeData(user); logger.info(`sendPortalLogout: SSO User ${JSON.stringify(user)} machineKey=${machineKey}`);
const data = coder.encodeData(user, machineKey);
if (!data) { if (!data) {
const errorMessage = `EncodeData is EMPTY`; throw new Error("EncodeData response is EMPTY", user, machineKey);
throw new Error(errorMessage);
//return res.redirect(urlResolver.getPortal500Url(req)); //return res.redirect(urlResolver.getPortal500Url(req));
} }

View File

@ -17,26 +17,25 @@
"use strict"; "use strict";
const config = require("../../config").get(), const hash = require("./hash");
hash = require("./hash");
var Coder = function() { var Coder = function() {
return { return {
encodeData: function(data) { encodeData: function(data, machinekey) {
if (!data && typeof (data) !== "object") if (!data && typeof (data) !== "object")
return undefined; return undefined;
const jsonStr = JSON.stringify(data); const jsonStr = JSON.stringify(data);
const dataEncoded = hash.encode(jsonStr, config["machinekey"] ? config["core"].machinekey : config.app.machinekey); const dataEncoded = hash.encode(jsonStr, machinekey);
return dataEncoded; return dataEncoded;
}, },
decodeData: function(data) { decodeData: function(data, machinekey) {
if (!data && typeof (data) !== "string") if (!data && typeof (data) !== "string")
return undefined; return undefined;
const jsonStr = hash.decode(data, config["core"].machinekey ? config["core"].machinekey : config.app.machinekey); const jsonStr = hash.decode(data, machinekey);
const dataDecoded = JSON.parse(jsonStr); const dataDecoded = JSON.parse(jsonStr);
return dataDecoded; return dataDecoded;

View File

@ -25,6 +25,7 @@ const _ = require("lodash");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const minifyXML = require("minify-xml").minify; const minifyXML = require("minify-xml").minify;
const logger = require("../log.js");
saml.setSchemaValidator(validator); saml.setSchemaValidator(validator);
@ -33,7 +34,7 @@ const IdentityProvider = saml.IdentityProvider;
const templDir = path.join(process.cwd(),"../../common/ASC.SsoAuth", "/app/templates/"); const templDir = path.join(process.cwd(),"../../common/ASC.SsoAuth", "/app/templates/");
module.exports = function (logger) { module.exports = function () {
function removeCertHead(cert) { function removeCertHead(cert) {
var newCert = cert; var newCert = cert;
if (cert && cert[0] === "-") { if (cert && cert[0] === "-") {
@ -283,5 +284,3 @@ module.exports = function (logger) {
}, },
}; };
}; };
//module.exports = Converter(logger);

View File

@ -1,7 +1,7 @@
/* /*
* *
* (c) Copyright Ascensio System Limited 2010-2021 * (c) Copyright Ascensio System Limited 2010-2021
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -12,73 +12,64 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
"use strict"; "use strict";
const logger = require("../log.js");
var Hash = function () { var Hash = function () {
var getHashBase64 = function (str) { var getHashBase64 = function (str) {
const crypto = require("crypto"); const crypto = require("crypto");
const sha256 = crypto.createHash("sha256"); const sha256 = crypto.createHash("sha256");
sha256.update(str, "utf8"); sha256.update(str, "utf8");
const result = sha256.digest("base64"); const result = sha256.digest("base64");
return result; return result;
}; };
return { return {
encode: function(str, secret) { encode: function (str, secret) {
try { try {
const strHash = getHashBase64(str + secret) + "?" + str; const strHash = getHashBase64(str + secret) + "?" + str;
let data = new Buffer(strHash).toString("base64"); let data = Buffer.from(strHash).toString("base64");
let cnt = 0; data = data.replace(/\+/g, "-").replace(/\//g, "_");
while (data.indexOf("=") !== -1) {
cnt++;
data = data.replace("=", "");
}
data = (data + cnt).replace(/\+/g, "-").replace(/\//g, "_"); return data;
} catch (ex) {
logger?.error("hash.encode", str, secret, ex);
return null;
}
},
decode: function (str, secret) {
try {
let strDecoded = Buffer.from(unescape(str), "base64").toString();
return data; const lastIndex = strDecoded.lastIndexOf("}");
} catch (ex) { if (lastIndex + 1 < strDecoded.length) {
return null; strDecoded = strDecoded.substring(0, lastIndex + 1);
}
},
decode: function(str, secret) {
try {
let strDecoded = Buffer.from(unescape(str), "base64").toString();
const lastIndex = strDecoded.lastIndexOf("}");
if (lastIndex + 1 < strDecoded.length) {
strDecoded = strDecoded.substring(0, lastIndex + 1);
}
const index = strDecoded.indexOf("?");
if (index > 0 && strDecoded[index + 1] == '{') {
let hash = strDecoded.substring(0, index);
let data = strDecoded.substring(index + 1);
if(getHashBase64(data + secret) === hash)
{
return data;
}
}
// Sig incorrect
return null;
} catch (ex) {
console.error("hash.decode", str, secret, ex);
return null;
}
} }
};
const index = strDecoded.indexOf("?");
if (index > 0 && strDecoded[index + 1] == "{") {
let hash = strDecoded.substring(0, index);
let data = strDecoded.substring(index + 1);
if (getHashBase64(data + secret) === hash) {
return data;
}
}
// Sig incorrect
return null;
} catch (ex) {
logger?.error("hash.decode", str, secret, ex);
return null;
}
},
};
}; };
module.exports = Hash(); module.exports = Hash();

View File

@ -18,11 +18,11 @@
"use strict"; "use strict";
const config = require("../../config").get(), const config = require("../../config").get(),
// ReSharper disable once InconsistentNaming logger = require("../log.js");
URL = require("url"); URL = require("url");
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
module.exports = function (logger) { module.exports = function () {
function getBaseUrl(req) { function getBaseUrl(req) {
const url = req.headers["x-rewriter-url"] || req.protocol + "://" + req.get("host"); const url = req.headers["x-rewriter-url"] || req.protocol + "://" + req.get("host");

View File

@ -95871,6 +95871,122 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>MetadataLoadError</name>
<description/>
<comment/>
<default_text/>
<translations>
<translation>
<language>az-Latn-AZ</language>
<approved>false</approved>
</translation>
<translation>
<language>bg-BG</language>
<approved>false</approved>
</translation>
<translation>
<language>cs-CZ</language>
<approved>false</approved>
</translation>
<translation>
<language>de-DE</language>
<approved>false</approved>
</translation>
<translation>
<language>el-GR</language>
<approved>false</approved>
</translation>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-ES</language>
<approved>false</approved>
</translation>
<translation>
<language>fi-FI</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-FR</language>
<approved>false</approved>
</translation>
<translation>
<language>hy-AM</language>
<approved>false</approved>
</translation>
<translation>
<language>it-IT</language>
<approved>false</approved>
</translation>
<translation>
<language>ja-JP</language>
<approved>false</approved>
</translation>
<translation>
<language>ko-KR</language>
<approved>false</approved>
</translation>
<translation>
<language>lo-LA</language>
<approved>false</approved>
</translation>
<translation>
<language>lv-LV</language>
<approved>false</approved>
</translation>
<translation>
<language>nl-NL</language>
<approved>false</approved>
</translation>
<translation>
<language>pl-PL</language>
<approved>false</approved>
</translation>
<translation>
<language>pt-BR</language>
<approved>false</approved>
</translation>
<translation>
<language>pt-PT</language>
<approved>false</approved>
</translation>
<translation>
<language>ro-RO</language>
<approved>false</approved>
</translation>
<translation>
<language>ru-RU</language>
<approved>false</approved>
</translation>
<translation>
<language>sk-SK</language>
<approved>false</approved>
</translation>
<translation>
<language>sl-SI</language>
<approved>false</approved>
</translation>
<translation>
<language>tr-TR</language>
<approved>false</approved>
</translation>
<translation>
<language>uk-UA</language>
<approved>false</approved>
</translation>
<translation>
<language>vi-VN</language>
<approved>false</approved>
</translation>
<translation>
<language>zh-CN</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>NameIDFormat</name> <name>NameIDFormat</name>
<description/> <description/>

View File

@ -1,7 +1,7 @@
{ {
"CannotChangePlan": "İstifadə olunan yaddaşın həcmi və ya admin/ekspert istifadəçilərin sayı seçilmiş planın məhdudiyyətlərini keçdiyi üçün planınızı dəyişə bilməzsiniz:", "CannotChangePlan": "İstifadə olunan yaddaşın həcmi və ya admin/ekspert istifadəçilərin sayı seçilmiş planın məhdudiyyətlərini keçdiyi üçün planınızı dəyişə bilməzsiniz:",
"ChangePricingPlan": "Qiymət planını dəyişdirin", "ChangePricingPlan": "Qiymət planını dəyişdirin",
"PlanStorageLimit": "Yeni tarifin məhdudiyyəti <1>{{yaddaşDəyəri}}</1> yaddaş və cari istifadə etdiyiniz yaddaş <1>{{cariYaddaşDəyəri}}</1>-dir.", "PlanStorageLimit": "Yeni tarifin məhdudiyyəti <1>{{storageValue}}</1> yaddaş və cari istifadə etdiyiniz yaddaş <1>{{currentStorageValue}}</1>-dir.",
"PlanUsersLimit": "Siz komandanı <1>{{istifadəçilərinSayı}}</1> admin/ekspert istifadəçi səviyyəsinə endirmək istəyirsiniz və DocSpace-də belə istifadəçilərin cari sayı <1>{{cariİstifadəçilərinSayı}}</1>-dir.", "PlanUsersLimit": "Siz komandanı <1>{{usersCount}}</1> admin/ekspert istifadəçi səviyyəsinə endirmək istəyirsiniz və DocSpace-də belə istifadəçilərin cari sayı <1>{{currentUsersCount}}</1>-dir.",
"SaveOrChange": "Bu DocSpace-in sahibi olaraq, hesabınızı silməzdən əvvəl sahibliyi başqa istifadəçiyə ötürməlisiniz. Davam etmək üçün yeni sahibkar seçin." "SaveOrChange": "Bu DocSpace-in sahibi olaraq, hesabınızı silməzdən əvvəl sahibliyi başqa istifadəçiyə ötürməlisiniz. Davam etmək üçün yeni sahibkar seçin."
} }

View File

@ -1,22 +1,22 @@
{ {
"Ascending": "Artan", "Ascending": "Artan",
"CopyWindowCode": "Pəncərə yerləşdirmə kodunu kopyalayın", "CopyWindowCode": "Pəncərənin kodunu kopyalayın",
"DataDisplay": "Məlumatların göstərilməsi parametrləri", "DataDisplay": "Məlumatların göstərilməsi parametrləri",
"Descending": "Azalan", "Descending": "Azalan",
"Destroy": "Məhv etmək", "Destroy": "Məhv etmək",
"EnterCount": "Sayını daxil edin", "EnterCount": "Sayı daxil edin",
"EnterHeight": "Hündürlüyü daxil edin", "EnterHeight": "Hündürlüyü daxil edin",
"EnterId": "ID daxil edin", "EnterId": "ID daxil edin",
"EnterPage": "Nömrə səhifəsini daxil edin", "EnterPage": "Səhifə nömrəsini daxil edin",
"EnterWidth": "Genişliyi daxil edin", "EnterWidth": "Eni daxil edin",
"FolderId": "Qovluq id", "FolderId": "Qovluq ID",
"FrameId": "Çərçivə id", "FrameId": "Çərçivə ID",
"Header": "Başlıq", "Header": "Başlıq",
"ItemsCount": "Maddələr sayılır", "ItemsCount": "Məhsulların sayı",
"JavascriptSdk": "Javascript SDK", "JavascriptSdk": "Javascript SDK",
"Menu": "Menyu", "Menu": "Menyu",
"Page": "Səhifə", "Page": "Səhifə",
"SearchTerm": "Axtarış termini", "SearchTerm": "Termin axtarın",
"SortOrder": "Sırala", "SortOrder": "Sıralamanı qaydaya salın",
"WindowParameters": "Pəncərə parametrləri" "WindowParameters": "Pəncərə parametrləri"
} }

View File

@ -1,19 +1,19 @@
{ {
"Ascending": "Възходящ", "Ascending": "Възходящ",
"CopyWindowCode": "Копирайте кода за вграждане на прозорец", "CopyWindowCode": "Копирайте кода за вграждане на прозореца",
"DataDisplay": "Настройки за показване на данни", "DataDisplay": "Настройки за дисплей на данните",
"Descending": "Низходящ", "Descending": "Низходящ",
"Destroy": "Унищожи", "Destroy": "Унищожи",
"EnterCount": "Въведете броя", "EnterCount": "Въведете броят",
"EnterHeight": "Въведете височина", "EnterHeight": "Въведете височината",
"EnterId": "Въведете id", "EnterId": "Въведете id",
"EnterPage": "Въведете номер на страницата", "EnterPage": "Въведете номера на страницата",
"EnterWidth": "Въведете ширина", "EnterWidth": "Въведете широчината",
"FolderId": "ID на папка", "FolderId": "Id на папката",
"FrameId": "ID на рамката", "FrameId": "Id на рамката",
"Header": "Заглавие", "Header": "Заглавие",
"ItemsCount": "Елементите се броят", "ItemsCount": "Брой елементи",
"JavascriptSdk": "Javascript SDK", "JavascriptSdk": "Javascript sdk",
"Menu": "Меню", "Menu": "Меню",
"Page": "Страница", "Page": "Страница",
"SearchTerm": "Термин за търсене", "SearchTerm": "Термин за търсене",

View File

@ -1,22 +1,22 @@
{ {
"Ascending": "Vzestupně", "Ascending": "Vzestupně",
"CopyWindowCode": "Kopírovat kód pro vložení okna", "CopyWindowCode": "Kopírování kódu pro vložení okna",
"DataDisplay": "Nastavení zobrazení dat", "DataDisplay": "Nastavení zobrazení dat",
"Descending": "Klesající", "Descending": "Sestupně",
"Destroy": "Zničit", "Destroy": "Zničit",
"EnterCount": "Zadejte počet", "EnterCount": "Zadejte počet",
"EnterHeight": "Zadejte výšku", "EnterHeight": "Zadejte výšku",
"EnterId": "Zadejte ID", "EnterId": "Zadejte id",
"EnterPage": "Zadejte číselnou stránku", "EnterPage": "Zadejte číslo stránky",
"EnterWidth": "Zadejte šířku", "EnterWidth": "Zadejte šířku",
"FolderId": "ID složky", "FolderId": "Id složky",
"FrameId": "ID snímku", "FrameId": "Id rámu",
"Header": "Záhlaví", "Header": "Záhlaví",
"ItemsCount": "Položky se počítají", "ItemsCount": "Počet položek",
"JavascriptSdk": "Javascript sdk", "JavascriptSdk": "Javascript sdk",
"Menu": "Jídelní lístek", "Menu": "Menu",
"Page": "Stránka", "Page": "Stránka",
"SearchTerm": "Hledaný výraz", "SearchTerm": "Hledaný termín",
"SortOrder": "Seřadit objednávku", "SortOrder": "Pořadí řazení",
"WindowParameters": "Parametry okna" "WindowParameters": "Parametry okna"
} }

View File

@ -1,22 +1,22 @@
{ {
"Ascending": "Ανερχόμενος", "Ascending": "Αύξουσα",
"CopyWindowCode": "Αντιγραφή κώδικα ενσωμάτωσης παραθύρου", "CopyWindowCode": "Αντιγραφή του κώδικα ενσωμάτωσης του παραθύρου",
"DataDisplay": "Ρυθμίσεις εμφάνισης δεδομένων", "DataDisplay": "Ρυθμίσεις εμφάνισης δεδομένων",
"Descending": "Φθίνων", "Descending": "Φθίνουσα",
"Destroy": "Καταστρέφω", "Destroy": "Καταστροφή",
"EnterCount": "Εισαγάγετε τον αριθμό", "EnterCount": "Εισάγετε μέτρηση",
"EnterHeight": "Εισαγάγετε ύψος", "EnterHeight": "Εισάγετε ύψος",
"EnterId": "Εισαγάγετε το αναγνωριστικό", "EnterId": "Εισάγετε αναγνωριστικού",
"EnterPage": "Εισαγάγετε τη σελίδα αριθμού", "EnterPage": "Εισάγετε αριθμό σελίδας",
"EnterWidth": "Εισαγάγετε πλάτος", "EnterWidth": "Εισάγετε πλάτος",
"FolderId": "Αναγνωριστικό φακέλου", "FolderId": "Αναγνωριστικό φακέλου",
"FrameId": "Ταυτότητα πλαισίου", "FrameId": "Αναγνωριστικό πλαισίου",
"Header": "Κεφαλίδα", "Header": "Κεφαλίδα",
"ItemsCount": "Τα στοιχεία μετράνε", "ItemsCount": "Αριθμός στοιχείων",
"JavascriptSdk": "Javascript sdk", "JavascriptSdk": "Javascript sdk",
"Menu": "Μενού", "Menu": "Μενού",
"Page": "Σελίδα", "Page": "Σελίδα",
"SearchTerm": "Ορος αναζήτησης", "SearchTerm": "Όρος αναζήτησης",
"SortOrder": "Σειρά ταξινόμησης", "SortOrder": "Σειρά ταξινόμησης",
"WindowParameters": "Παράμετροι παραθύρου" "WindowParameters": "Παράμετροι παραθύρου"
} }

View File

@ -1,7 +1,7 @@
{ {
"CannotChangePlan": "Et voi muuttaa ohjelmaasi, koska käytetyn muistin määrä tai ylläpitäjien/tehokäyttäjien määrä ylittää valitun ohjelman rajoitukset:", "CannotChangePlan": "Et voi muuttaa ohjelmaasi, koska käytetyn muistin määrä tai ylläpitäjien/tehokäyttäjien määrä ylittää valitun ohjelman rajoitukset:",
"ChangePricingPlan": "Muuta hinnoitteluohjelmaa", "ChangePricingPlan": "Muuta hinnoitteluohjelmaa",
"PlanStorageLimit": "Uuden tariffin rajoitus on <1>{{MuistinMäärä}}</1> muistista ja käytetyn muistin määrä on <1>{{NykyinenMuistinMäärä}}</1>.", "PlanStorageLimit": "Uuden tariffin rajoitus on <1>{{storageValue}}</1> muistista ja käytetyn muistin määrä on <1>{{currentStorageValue}}</1>.",
"PlanUsersLimit": "Haluat alentaa tiimin<1>{{KäyttäjienMäärä}}</1>ylläpitäjiksi/tehokäyttäjiksi ja nykyinen määrä sellaisia käyttäjiä DocSpacessasi on <1>{{nykyisten KäyttäjienMäärä}}</1>.", "PlanUsersLimit": "Haluat alentaa tiimin<1>{{usersCount}}</1>ylläpitäjiksi/tehokäyttäjiksi ja nykyinen määrä sellaisia käyttäjiä DocSpacessasi on <1>{{currentUsersCount}}</1>.",
"SaveOrChange": "DocSpacen omistajana, sinun tulee siirtää omistajuus toiselle käyttäjälle ennen kuin voit poistaa tilisi. Ole hyvä ja valitse uusi omistaja jatkaaksesi." "SaveOrChange": "DocSpacen omistajana, sinun tulee siirtää omistajuus toiselle käyttäjälle ennen kuin voit poistaa tilisi. Ole hyvä ja valitse uusi omistaja jatkaaksesi."
} }

View File

@ -3,6 +3,6 @@
"ChangeUserTypeHeader": "사용자 유형 변경", "ChangeUserTypeHeader": "사용자 유형 변경",
"ChangeUserTypeMessage": "'{{ firstType }}' 유형 사용자가 '{{ secondType }}' 유형으로 이동됩니다.", "ChangeUserTypeMessage": "'{{ firstType }}' 유형 사용자가 '{{ secondType }}' 유형으로 이동됩니다.",
"ChangeUserTypeMessageMulti": "선택한 사용자가 '{{ secondType }}' 유형으로 이동됩니다.", "ChangeUserTypeMessageMulti": "선택한 사용자가 '{{ secondType }}' 유형으로 이동됩니다.",
"ChangeUserTypeMessageWarning": "DocSpace관리자 및 자신의 유형을 변경할 수 없습니다", "ChangeUserTypeMessageWarning": "DocSpace관리자 및 자신의 유형을 변경할 수 없습니다.",
"SuccessChangeUserType": "사용자 유형이 성공적으로 변경되었습니다" "SuccessChangeUserType": "사용자 유형이 성공적으로 변경되었습니다"
} }

View File

@ -1,5 +1,5 @@
{ {
"EmptyScreenDescription": "인터넷 연결을 확인한 뒤 페이지를 새로 고침하거나 나중에 시도하세요", "EmptyScreenDescription": "인터넷 연결을 확인한 뒤 페이지를 새로 고침하거나 나중에 시도하세요.",
"GalleryEmptyScreenDescription": "세부 정보를 보려면 양식 템플릿을 선택하세요", "GalleryEmptyScreenDescription": "세부 정보를 보려면 양식 템플릿을 선택하세요",
"GalleryEmptyScreenHeader": "양식 템플릿을 로드하지 못했습니다", "GalleryEmptyScreenHeader": "양식 템플릿을 로드하지 못했습니다",
"TemplateInfo": "템플릿 정보" "TemplateInfo": "템플릿 정보"

View File

@ -1,15 +1,15 @@
{ {
"Ascending": "오름차순", "Ascending": "오름차순",
"CopyWindowCode": " 임베드 코드 복사", "CopyWindowCode": "윈도우 임베드 코드 복사",
"DataDisplay": "데이터 표시 설정", "DataDisplay": "데이터 표시 설정",
"Descending": "내림차순", "Descending": "내림차순",
"Destroy": "파괴하다", "Destroy": "파괴",
"EnterCount": "개수 입력", "EnterCount": "개수 입력",
"EnterHeight": "높이 입력", "EnterHeight": "높이 입력",
"EnterId": "아이디 입력", "EnterId": "ID 입력",
"EnterPage": "번호 입력 페이지", "EnterPage": "페이지 번호 입력",
"EnterWidth": " 입력", "EnterWidth": "너비 입력",
"FolderId": "폴더 아이디", "FolderId": "폴더 ID",
"FrameId": "프레임 ID", "FrameId": "프레임 ID",
"Header": "머리글", "Header": "머리글",
"ItemsCount": "항목 수", "ItemsCount": "항목 수",

View File

@ -7,7 +7,7 @@
"Notifications": "알림", "Notifications": "알림",
"RoomsActions": "방 내 파일 관련 작업", "RoomsActions": "방 내 파일 관련 작업",
"RoomsActivity": "방 활동", "RoomsActivity": "방 활동",
"RoomsActivityDescription": "시간별 알림. 방의 모든 활동에 대한 최신 정보를 받아보세요", "RoomsActivityDescription": "시간별 알림. 방의 모든 활동에 대한 최신 정보를 받아보세요.",
"UsefulTips": "유용한 DocSpace 팁", "UsefulTips": "유용한 DocSpace 팁",
"UsefulTipsDescription": "DocSpace에 대한 유용한 가이드 얻기" "UsefulTipsDescription": "DocSpace에 대한 유용한 가이드 얻기"
} }

View File

@ -4,7 +4,7 @@
"Benefits": "혜택", "Benefits": "혜택",
"BusinessExpired": "{{planName}} 요금제가 {{date}}에 만료됩니다", "BusinessExpired": "{{planName}} 요금제가 {{date}}에 만료됩니다",
"BusinessFinalDateInfo": "구독이 {{finalDate}}에 업데이트된 요금 및 사양으로 자동 갱신됩니다. Stripe 고객 포털에서 취소하거나 청구 정보를 변경할 수 있습니다.", "BusinessFinalDateInfo": "구독이 {{finalDate}}에 업데이트된 요금 및 사양으로 자동 갱신됩니다. Stripe 고객 포털에서 취소하거나 청구 정보를 변경할 수 있습니다.",
"BusinessPlanPaymentOverdue": "새 사용자를 추가하고 새 방을 만들 수 없습니다. {{planName}} 요금제가 연체되었습니다", "BusinessPlanPaymentOverdue": "새 사용자를 추가하고 새 방을 만들 수 없습니다. {{planName}} 요금제가 연체되었습니다.",
"BusinessRequestDescription": "{{peopleNumber}}명 이상의 관리자/고급 사용자가 포함된 요금제는 요청 시에만 제공됩니다.", "BusinessRequestDescription": "{{peopleNumber}}명 이상의 관리자/고급 사용자가 포함된 요금제는 요청 시에만 제공됩니다.",
"BusinessSuggestion": "{{planName}} 요금제를 사용자 지정하세요", "BusinessSuggestion": "{{planName}} 요금제를 사용자 지정하세요",
"BusinessTitle": "{{planName}} 요금제를 사용 중입니다", "BusinessTitle": "{{planName}} 요금제를 사용 중입니다",

View File

@ -14,9 +14,9 @@
"AdminsMessageDescription": "관리자 메시지 설정은 DocSpace 관리자에게 연락하는 방법입니다.", "AdminsMessageDescription": "관리자 메시지 설정은 DocSpace 관리자에게 연락하는 방법입니다.",
"AdminsMessageHelper": "사람들이 DocSpace에 액세스하는 데 문제가 있는 경우 관리자에게 메시지를 보낼 수 있도록 로그인 페이지에 연락처 양식을 표시하려면 이 옵션을 활성화하세요.", "AdminsMessageHelper": "사람들이 DocSpace에 액세스하는 데 문제가 있는 경우 관리자에게 메시지를 보낼 수 있도록 로그인 페이지에 연락처 양식을 표시하려면 이 옵션을 활성화하세요.",
"AllDomains": "모든 도메인", "AllDomains": "모든 도메인",
"AmazonBucketTip": "백업을 저장하려는 Amazon S3 버킷의 고유한 이름을 입력하세요", "AmazonBucketTip": "백업을 저장하려는 Amazon S3 버킷의 고유한 이름을 입력하세요.",
"AmazonCSE": "클라이언트측 암호화", "AmazonCSE": "클라이언트측 암호화",
"AmazonForcePathStyleTip": "True인 경우 요청은 항상 경로 스타일 주소 지정을 사용합니다 ", "AmazonForcePathStyleTip": "True인 경우 요청은 항상 경로 스타일 주소 지정을 사용합니다 .",
"AmazonHTTPTip": "이 속성을 True로 설정하면 클라이언트는 대상 엔드포인트가 지원하는 경우 HTTP 프로토콜을 사용하려고 시도합니다. 기본적으로 이 속성은 False로 설정됩니다.", "AmazonHTTPTip": "이 속성을 True로 설정하면 클라이언트는 대상 엔드포인트가 지원하는 경우 HTTP 프로토콜을 사용하려고 시도합니다. 기본적으로 이 속성은 False로 설정됩니다.",
"AmazonRegionTip": "Amazon 버킷이 있는 AWS 지역을 입력하세요.", "AmazonRegionTip": "Amazon 버킷이 있는 AWS 지역을 입력하세요.",
"AmazonSSE": "서버측 암호화", "AmazonSSE": "서버측 암호화",
@ -39,7 +39,7 @@
"Branding": "브랜딩", "Branding": "브랜딩",
"BrandingSectionDescription": "회사 정보를 지정하고 DocSpace 인터페이스 내에 표시되는 이메일 주소 및 외부 리소스에 대한 링크를 추가하세요.", "BrandingSectionDescription": "회사 정보를 지정하고 DocSpace 인터페이스 내에 표시되는 이메일 주소 및 외부 리소스에 대한 링크를 추가하세요.",
"BrandingSubtitle": "사용자에게 브랜드 경험을 제공하려면 이 옵션을 사용하세요.", "BrandingSubtitle": "사용자에게 브랜드 경험을 제공하려면 이 옵션을 사용하세요.",
"BreakpointWarningText": "이 섹션은 데스크톱 버전에서만 사용할 수 있습니다.", "BreakpointWarningText": "이 섹션은 데스크톱 버전에서만 사용할 수 있습니다",
"BreakpointWarningTextPrompt": "<1>{{sectionName}}</1> 설정에 액세스하려면 데스크톱 사이트를 사용하세요.", "BreakpointWarningTextPrompt": "<1>{{sectionName}}</1> 설정에 액세스하려면 데스크톱 사이트를 사용하세요.",
"ButtonsColor": "버튼", "ButtonsColor": "버튼",
"ByApp": "인증 앱 이용", "ByApp": "인증 앱 이용",

View File

@ -1,22 +1,22 @@
{ {
"Ascending": "Oplopend", "Ascending": "Oplopend",
"CopyWindowCode": "Kopieer de insluitcode van het venster", "CopyWindowCode": "Kopieer venster insluitcode",
"DataDisplay": "Instellingen voor gegevensweergave", "DataDisplay": "Instellingen weergave gegevens",
"Descending": "Aflopend", "Descending": "Aflopend",
"Destroy": "Vernietigen", "Destroy": "Vernietig",
"EnterCount": "Voer het aantal in", "EnterCount": "Voer aantal in",
"EnterHeight": "Voer Hoogte in", "EnterHeight": "Voer hoogte in",
"EnterId": "Voer ID in", "EnterId": "Voor IDin",
"EnterPage": "Voer nummerpagina in", "EnterPage": "Voor nummer pagina in",
"EnterWidth": "Voer de breedte in", "EnterWidth": "Voor breedte",
"FolderId": "Map-ID", "FolderId": "Map ID",
"FrameId": "Frame-ID", "FrameId": "Frame ID",
"Header": "Koptekst", "Header": "Koptekst",
"ItemsCount": "Artikelen tellen", "ItemsCount": "Items aantal",
"JavascriptSdk": "Javascript-sdk", "JavascriptSdk": "Javascript sdk",
"Menu": "Menu", "Menu": "Menu",
"Page": "Pagina", "Page": "Pagina",
"SearchTerm": "Zoekterm", "SearchTerm": "Zoekterm",
"SortOrder": "Sorteervolgorde", "SortOrder": "Sorteer volgorde",
"WindowParameters": "Venster parameters" "WindowParameters": "Venster parameters"
} }

View File

@ -1,22 +1,22 @@
{ {
"Ascending": "Rosnąco", "Ascending": "Rosnąco",
"CopyWindowCode": "Skopiuj kod osadzania okna", "CopyWindowCode": "Skopiuj kod osadzania dla okna",
"DataDisplay": "Ustawienia wyświetlania danych", "DataDisplay": "Ustawienia wyświetlania danych",
"Descending": "Malejąco", "Descending": "Malejąco",
"Destroy": "Zniszcz", "Destroy": "Zniszcz",
"EnterCount": "Wpisz liczbę", "EnterCount": "Wpisz liczbę",
"EnterHeight": "Wprowadź wysokość", "EnterHeight": "Wpisz wysokość",
"EnterId": "Wprowadź identyfikator", "EnterId": "Wpisz ID",
"EnterPage": "Wprowadź numer strony", "EnterPage": "Wpisz numer strony",
"EnterWidth": "Wprowadź szerokość", "EnterWidth": "Wpisz szerokość",
"FolderId": "Identyfikator folderu", "FolderId": "ID katalogu",
"FrameId": "Identyfikator ramki", "FrameId": "ID ramki",
"Header": "Nagłówek", "Header": "Nagłówek",
"ItemsCount": "Liczba przedmiotów", "ItemsCount": "Liczba pozycji",
"JavascriptSdk": "SDK JavaScript", "JavascriptSdk": "SDK Javascript",
"Menu": "Menu", "Menu": "Menu",
"Page": "Strona", "Page": "Strona",
"SearchTerm": "Szukany termin", "SearchTerm": "Wyszukaj frazę",
"SortOrder": "Kolejność sortowania", "SortOrder": "Kolejność",
"WindowParameters": "Parametry okna" "WindowParameters": "Parametry okna"
} }

View File

@ -1,22 +1,22 @@
{ {
"Ascending": "Stúpajúca", "Ascending": "Vzostupne",
"CopyWindowCode": "Kopírovať kód na vloženie okna", "CopyWindowCode": "Kopírovať kód na vloženie okna",
"DataDisplay": "Nastavenia zobrazovania údajov", "DataDisplay": "Nastavenia zobrazovania údajov",
"Descending": "Zostupne", "Descending": "Zostupne",
"Destroy": "Zničiť", "Destroy": "Zničiť",
"EnterCount": "Zadajte počet", "EnterCount": "Zadajte počet",
"EnterHeight": "Zadajte výšku", "EnterHeight": "Zadajte výšku",
"EnterId": "Zadajte ID", "EnterId": "Zadajte id",
"EnterPage": "Zadajte stránku s číslom", "EnterPage": "Zadajte číslo strany",
"EnterWidth": "Zadajte šírku", "EnterWidth": "Zadajte šírku",
"FolderId": "ID priečinka", "FolderId": "ID priečinka",
"FrameId": "ID rámu", "FrameId": "ID rámu",
"Header": "Hlavička", "Header": "Hlavička",
"ItemsCount": "Položky sa počítajú", "ItemsCount": "Počet položiek",
"JavascriptSdk": "Javascript sdk", "JavascriptSdk": "Javascript sdk",
"Menu": "Ponuka", "Menu": "Menu",
"Page": "Strana", "Page": "Strana",
"SearchTerm": "Hľadaný výraz", "SearchTerm": "Hľadať termín",
"SortOrder": "Zoradiť objednávku", "SortOrder": "Zoradiť objednávku",
"WindowParameters": "Parametre okna" "WindowParameters": "Parametre okna"
} }

View File

@ -3,20 +3,20 @@
"CopyWindowCode": "Kopiraj kodo za vdelavo okna", "CopyWindowCode": "Kopiraj kodo za vdelavo okna",
"DataDisplay": "Nastavitve prikaza podatkov", "DataDisplay": "Nastavitve prikaza podatkov",
"Descending": "Padajoče", "Descending": "Padajoče",
"Destroy": "Uničiti", "Destroy": "Uniči",
"EnterCount": "Vnesite štetje", "EnterCount": "Vnesi število",
"EnterHeight": "Vnesite višino", "EnterHeight": "Vnesi višino",
"EnterId": "Vnesite id", "EnterId": "Vnesi ID",
"EnterPage": "Vnesite številko strani", "EnterPage": "Vnesi številko strani",
"EnterWidth": "Vnesite širino", "EnterWidth": "Vnesi širino",
"FolderId": "ID mape", "FolderId": "ID mape",
"FrameId": "ID okvirja", "FrameId": "ID okvirja",
"Header": "Glava", "Header": "Glava",
"ItemsCount": "Predmeti štejejo", "ItemsCount": "Število elementov",
"JavascriptSdk": "Javascript sdk", "JavascriptSdk": "Javascript sdk",
"Menu": "MENU", "Menu": "Meni",
"Page": "Stran", "Page": "Stran",
"SearchTerm": "Iskalni izraz", "SearchTerm": "Išči izraz",
"SortOrder": "Vrstni red", "SortOrder": "Vrstni red",
"WindowParameters": "Parametri oken" "WindowParameters": "Parametri oken"
} }

View File

@ -1,9 +1,9 @@
{ {
"Ascending": "Artan", "Ascending": "Artan",
"CopyWindowCode": "Pencere yerleştirme kodunu kopyala", "CopyWindowCode": "Pencere gömülü kodunu kopyala",
"DataDisplay": "Veri görüntüleme ayarları", "DataDisplay": "Veri görüntüleme ayarları",
"Descending": "Azalan", "Descending": "Azalan",
"Destroy": "Yıkmak", "Destroy": "İmha et",
"EnterCount": "Sayı girin", "EnterCount": "Sayı girin",
"EnterHeight": "Yüksekliği girin", "EnterHeight": "Yüksekliği girin",
"EnterId": "Kimliği girin", "EnterId": "Kimliği girin",
@ -13,7 +13,7 @@
"FrameId": "Çerçeve kimliği", "FrameId": "Çerçeve kimliği",
"Header": "Üst Bilgi", "Header": "Üst Bilgi",
"ItemsCount": "Ürün sayısı", "ItemsCount": "Ürün sayısı",
"JavascriptSdk": "Javascript SDK'sı", "JavascriptSdk": "Javascript sdk'sı",
"Menu": "Menü", "Menu": "Menü",
"Page": "Sayfa", "Page": "Sayfa",
"SearchTerm": "Arama terimi", "SearchTerm": "Arama terimi",

View File

@ -1,22 +1,22 @@
{ {
"Ascending": "Висхідний", "Ascending": "За зростанням",
"CopyWindowCode": "Скопіюйте код вбудовування вікна", "CopyWindowCode": "Скопіювати код вбудовування вікна",
"DataDisplay": "Налаштування відображення даних", "DataDisplay": "Параметри відображення даних",
"Descending": "Спускається", "Descending": "За спаданням",
"Destroy": "Знищити", "Destroy": "За спаданням",
"EnterCount": "Введіть кількість", "EnterCount": "Введіть кількість",
"EnterHeight": "Введіть висоту", "EnterHeight": "Введіть висоту",
"EnterId": "Введіть id", "EnterId": "Введіть ідентифікатор",
"EnterPage": "Введіть номер сторінки", "EnterPage": "Введіть номер сторінки",
"EnterWidth": "Введіть ширину", "EnterWidth": "Введіть ширину",
"FolderId": "Ідентифікатор папки", "FolderId": "Ідентифікатор папки",
"FrameId": "Ідентифікатор кадру", "FrameId": "Ідентифікатор фрейму",
"Header": "Заголовок", "Header": "Заголовок",
"ItemsCount": "Кількість елементів", "ItemsCount": "Кількість елементів",
"JavascriptSdk": "Javascript SDK", "JavascriptSdk": "SDK Javascript",
"Menu": "Меню", "Menu": "Меню",
"Page": "Сторінка", "Page": "Сторінка",
"SearchTerm": "Пошуковий термін", "SearchTerm": "Пошуковий запит",
"SortOrder": "Порядок сортування", "SortOrder": "Порядок сортування",
"WindowParameters": "Параметри вікна" "WindowParameters": "Параметри вікна"
} }

View File

@ -3,5 +3,6 @@
"AboutHeader": "Về chương trình này", "AboutHeader": "Về chương trình này",
"DocumentManagement": "Quản lý tài liệu", "DocumentManagement": "Quản lý tài liệu",
"OnlineEditors": "Người chỉnh sửa trực tuyến", "OnlineEditors": "Người chỉnh sửa trực tuyến",
"Site": "Trang web",
"SoftwareLicense": "Giấy phép phần mềm" "SoftwareLicense": "Giấy phép phần mềm"
} }

View File

@ -1 +1,8 @@
{} {
"ArchiveHeader": "Chuyển đến Sao lưu?",
"ArchiveRoom": "Bạn sắp sao lưu một phòng.",
"ArchiveRooms": "Bạn sắp sao lưu các phòng.",
"RestoreAllRooms": "Bạn có chắc chắn muốn khôi phục tất cả các phòng không?",
"RestoreRoom": "Bạn có chắc chắn muốn khôi phục phòng không?",
"RestoreRooms": "Bạn có chắc chắn muốn khôi phục các phòng không?"
}

View File

@ -1,5 +1,14 @@
{ {
"AppointAdmin": "Chỉ định quản trị viên",
"BackupPortal": "Sao lưu dữ liệu cổng thông tin", "BackupPortal": "Sao lưu dữ liệu cổng thông tin",
"ChangeInstruction": "Để thay đổi chủ sở hữu DocSpace, xin vui lòng chọn tên của chủ sở hữu mới bên dưới.",
"ChangeOwner": "Thay đổi chủ sở hữu DocSpace",
"ChangeUser": "Thay đổi người dùng",
"DeactivateOrDeletePortal": "Vô hiệu hóa hoặc xóa DocSpace",
"DoTheSame": "Làm tương tự như quản trị viên",
"ManagePortal": "Quản lý cấu hình cổng thông tin", "ManagePortal": "Quản lý cấu hình cổng thông tin",
"ManageUser": "Quản lý tài khoản người dùng" "ManageUser": "Quản lý tài khoản người dùng",
"NewPortalOwner": "Chủ sở hữu DocSpace mới",
"PortalOwnerCan": "Chủ sở hữu DocSpace có thể:",
"SetAccessRights": "Đặt quyền truy cập"
} }

View File

@ -1,4 +1,7 @@
{ {
"ChangeUserStatusDialog": "Người dùng có trạng thái '{{ userStatus }}' sẽ bị {{ status }}.", "ChangeUserStatusDialog": "Người dùng có trạng thái '{{ userStatus }}' sẽ bị {{ status }}.",
"ChangeUserStatusDialogHeader": "Thay đổi trạng thái người dùng" "ChangeUserStatusDialogHeader": "Thay đổi trạng thái người dùng",
"ChangeUserStatusDialogMessage": "Bạn không thể thay đổi trạng thái cho chủ sở hữu DocSpace và cho chính mình.",
"ChangeUsersActiveStatus": "Đã bật",
"ChangeUsersDisableStatus": "Đã tắt"
} }

View File

@ -2,5 +2,7 @@
"ChangeUserTypeButton": "Thay đổi loại", "ChangeUserTypeButton": "Thay đổi loại",
"ChangeUserTypeHeader": "Thay đổi loại người dùng", "ChangeUserTypeHeader": "Thay đổi loại người dùng",
"ChangeUserTypeMessage": "Người dùng loại '{{ firstType }}' sẽ được chuyển sang loại '{{ secondType }}'.", "ChangeUserTypeMessage": "Người dùng loại '{{ firstType }}' sẽ được chuyển sang loại '{{ secondType }}'.",
"ChangeUserTypeMessageMulti": "Người dùng đã chọn sẽ được chuyển sang loại '{{ secondType }}'.",
"ChangeUserTypeMessageWarning": "Bạn không thể thay đổi kiểu cho người quản trị DocSpace và cho chính mình.",
"SuccessChangeUserType": "Loại người dùng đã được thay đổi thành công" "SuccessChangeUserType": "Loại người dùng đã được thay đổi thành công"
} }

View File

@ -17,9 +17,17 @@
"InviteTitle": "Bạn được mời tham gia cổng thông tin này!", "InviteTitle": "Bạn được mời tham gia cổng thông tin này!",
"LoginRegistryButton": "Tham gia", "LoginRegistryButton": "Tham gia",
"PassworResetTitle": "Bây giờ bạn có thể tạo mật khẩu mới.", "PassworResetTitle": "Bây giờ bạn có thể tạo mật khẩu mới.",
"PhoneSubtitle": "Xác thực hai yếu tố được kích hoạt để cung cấp bảo mật bổ sung. Hãy nhập số điện thoại di động của bạn để tiếp tục làm việc trong DocSpace. Phải nhập số điện thoại di động theo định dạng quốc tế có mã quốc gia.",
"PortalContinueTitle": "Xin vui lòng xác nhận rằng bạn muốn kích hoạt lại DocSpace của mình.",
"PortalDeactivateTitle": "Xin vui lòng xác nhận rằng bạn muốn vô hiệu hóa DocSpace của mình.",
"PortalRemoveTitle": "Xin vui lòng xác nhận rằng bạn muốn xóa DocSpace của mình.",
"Reactivate": "Kích hoạt lại",
"SetAppButton": "Kết nối ứng dụng", "SetAppButton": "Kết nối ứng dụng",
"SetAppDescription": "Xác thực hai yếu tố đã được bật. Hãy thiết lập cấu hình ứng dụng trình xác thực của bạn để tiếp tục hoạt động trên cổng thông tin. Bạn có thể sử dụng Google Authenticator cho <1> Android </1>và<4> iOS </4>hoặc Authenticator cho <8>Điện thoại Windows</8>. ", "SetAppDescription": "Xác thực hai yếu tố đã được bật. Hãy thiết lập cấu hình ứng dụng trình xác thực của bạn để tiếp tục hoạt động trên cổng thông tin. Bạn có thể sử dụng Google Authenticator cho <1> Android </1>và<4> iOS </4>hoặc Authenticator cho <8>Điện thoại Windows</8>. ",
"SetAppInstallDescription": "Để kết nối ứng dụng, hãy quét mã QR hoặc tự nhập mã khóa bí mật của bạn <1>{{ secretKey }}</1>, rồi nhập mã gồm 6 chữ số từ ứng dụng của bạn vào trường bên dưới. ", "SetAppInstallDescription": "Để kết nối ứng dụng, hãy quét mã QR hoặc tự nhập mã khóa bí mật của bạn <1>{{ secretKey }}</1>, rồi nhập mã gồm 6 chữ số từ ứng dụng của bạn vào trường bên dưới. ",
"SetAppTitle": "Thiết lập cấu hình ứng dụng xác thực của bạn", "SetAppTitle": "Thiết lập cấu hình ứng dụng xác thực của bạn",
"SuccessDeactivate": "Tài khoản của bạn đã bị vô hiệu hóa thành công. Trong 10 giây, bạn sẽ được chuyển hướng đến <1>trang</1>.",
"SuccessReactivate": "Tài khoản của bạn đã được kích hoạt lại thành công. Trong 10 giây, bạn sẽ được chuyển hướng đến <1>không gian</1>.",
"SuccessRemoved": "Tài khoản của bạn đã được xóa thành công. Trong vòng 10 giây, bạn sẽ được chuyển hướng đến <1>trang</1>.",
"WelcomeUser": "Chào mừng bạn đến với cổng thông tin của chúng tôi!\nĐể bắt đầu, hãy đăng ký, hoặc đăng nhập qua mạng xã hội." "WelcomeUser": "Chào mừng bạn đến với cổng thông tin của chúng tôi!\nĐể bắt đầu, hãy đăng ký, hoặc đăng nhập qua mạng xã hội."
} }

View File

@ -3,5 +3,6 @@
"ConnectFolderTitle": "Tiêu đề thư mục ", "ConnectFolderTitle": "Tiêu đề thư mục ",
"ConnectionUrl": "Url kết nối", "ConnectionUrl": "Url kết nối",
"Login": "Đăng nhập", "Login": "Đăng nhập",
"Reconnect": "Kết nối lại" "Reconnect": "Kết nối lại",
"SuccessfulConnectionOfAThirdParty": "Dịch vụ của bên thứ ba đã được kết nối thành công."
} }

View File

@ -1,6 +1,9 @@
{ {
"ConversionMessage": "Tất cả tài liệu bạn tải lên sẽ được chuyển đổi sang định dạng Office Open XML (docx, xlsx hoặc pptx) để chỉnh sửa nhanh hơn.", "ConversionMessage": "Tất cả tài liệu bạn tải lên sẽ được chuyển đổi sang định dạng Office Open XML (docx, xlsx hoặc pptx) để chỉnh sửa nhanh hơn.",
"ConvertedFileDestination": "Bản sao của file sẽ được tạo trong thư mục <strong>{{folderTitle}}</strong>.", "ConvertedFileDestination": "Bản sao của file sẽ được tạo trong thư mục <strong>{{folderTitle}}</strong>.",
"DocumentConversionTitle": "Chuyển đổi tài liệu",
"FailedToConvert": "Không thể chuyển đổi",
"FileUploadTitle": "Tải tập tin lên",
"HideMessage": "Không hiển thị lại thông báo này", "HideMessage": "Không hiển thị lại thông báo này",
"InfoCreateFileIn": "File '{{fileTitle}}' được tạo trong '{{folderTitle}}'", "InfoCreateFileIn": "File '{{fileTitle}}' được tạo trong '{{folderTitle}}'",
"OpenFileMessage": "Tài liệu bạn mở sẽ được chuyển sang định dạng Office Open XML giúp sửa và xem nhanh hơn.", "OpenFileMessage": "Tài liệu bạn mở sẽ được chuyển sang định dạng Office Open XML giúp sửa và xem nhanh hơn.",

View File

@ -1 +1,27 @@
{} {
"ChooseRoomType": "Chọn loại phòng",
"CollaborationRoomDescription": "Cộng tác trên một hoặc nhiều tài liệu với nhóm của bạn",
"CollaborationRoomTitle": "Phòng cộng tác",
"CreateRoomConfirmation": "Tiếp tục mà không cần kết nối bộ nhớ?\nBạn đã chọn tùy chọn bộ nhớ của bên thứ ba chưa được kết nối. Nếu bạn tiếp tục mà không kết nối dịch vụ, tùy chọn này sẽ không được thêm vào.",
"CreateTagOption": "Tạo thẻ tag",
"CustomRoomDescription": "Áp dụng cài đặt của riêng bạn để sử dụng trong phòng này cho bất kỳ mục đích nào theo yêu cầu.",
"CustomRoomTitle": "Phòng tùy chỉnh",
"FillingFormsRoomDescription": "Xây dựng, chia sẻ và điền vào các mẫu tài liệu hoặc làm việc với các cài đặt sẵn để nhanh chóng tạo bất kỳ loại tài liệu nào.",
"FillingFormsRoomTitle": "Phòng điền vào các mẫu",
"Icon": "Biểu tượng",
"MakeRoomPrivateDescription": "Tất cả các tập tin trong phòng này sẽ được mã hóa.",
"MakeRoomPrivateLimitationsWarningDescription": "Với tính năng này, bạn chỉ có thể mời người dùng DocSpace hiện có. Sau khi tạo một phòng, bạn sẽ không thể thay đổi danh sách người dùng.",
"MakeRoomPrivateTitle": "Đặt phòng ở Chế độ Riêng tư",
"ReviewRoomDescription": "Yêu cầu xem xét hoặc nhận xét về tài liệu",
"ReviewRoomTitle": "Phòng phê duyệt",
"RoomEditing": "Chỉnh sửa phòng",
"RootLabel": "Gốc",
"TagsPlaceholder": "Thêm thẻ",
"ThirdPartyStorageComboBoxPlaceholder": "Chọn bộ nhớ",
"ThirdPartyStorageDescription": "Sử dụng dịch vụ của bên thứ ba làm nơi lưu trữ dữ liệu cho phòng này. Một thư mục mới để lưu trữ dữ liệu của phòng này sẽ được tạo trong bộ nhớ được kết nối.",
"ThirdPartyStorageNoStorageAlert": "Trước tiên, bạn cần kết nối dịch vụ tương ứng trong phần 'Tích hợp'. Nếu không, kết nối sẽ không thể thực hiện được.",
"ThirdPartyStoragePermanentSettingDescription": "Các tập tin được lưu trữ trong bộ nhớ của bên thứ ba {{thirdpartyTitle}} trong thư mục \"{{thirdpartyFolderName}}\".\n<strong>{{thirdpartyPath}}</strong>",
"ThirdPartyStorageRoomAdminNoStorageAlert": "Để kết nối bộ nhớ của bên thứ ba, bạn cần thêm dịch vụ tương ứng trong phần Tích hợp của cài đặt DocSpace. Liên hệ với chủ sở hữu hoặc quản trị viên DocSpace để kích hoạt tích hợp.",
"ViewOnlyRoomDescription": "Chia sẻ bất kỳ tài liệu, báo cáo, hồ sơ, và các tập tin sẵn sàng khác để xem.",
"ViewOnlyRoomTitle": "Phòng chỉ xem"
}

View File

@ -1,5 +1,15 @@
{ {
"DeleteFile": "Bạn sắp xóa tập tin này. Bạn có chắc chắn muốn tiếp tục không?",
"DeleteFolder": "Bạn sắp xóa thư mục này. Bạn có chắc chắn muốn tiếp tục không?",
"DeleteItems": "Bạn sắp xóa các mục này. Bạn có chắc chắn muốn tiếp tục không?",
"DeleteRoom": "Bạn sắp xóa phòng này. Bạn sẽ không thể khôi phục nó.",
"DeleteRooms": "Bạn sắp xóa các phòng này. Bạn sẽ không thể khôi phục chúng.",
"MoveToTrashButton": "Chuyển vào Thùng rác", "MoveToTrashButton": "Chuyển vào Thùng rác",
"MoveToTrashFile": "Bạn sắp xóa tập tin này. Xin lưu ý rằng nếu bạn đã chia sẻ nó với ai đó, nó sẽ không khả dụng. Tập tin sẽ bị xóa vĩnh viễn trong 30 ngày. Bạn có chắc chắn muốn tiếp tục không?",
"MoveToTrashFolder": "Bạn sắp xóa thư mục này. Xin lưu ý rằng nếu bạn đã chia sẻ nó với ai đó, nó sẽ không khả dụng. Bạn có chắc chắn muốn tiếp tục không?",
"MoveToTrashFolderFromPersonal": "Bạn sắp xóa thư mục này. Bạn có chắc chắn muốn tiếp tục không?",
"MoveToTrashItems": "Bạn sắp xóa các mục này. Xin lưu ý rằng nếu bạn đã chia sẻ chúng với ai đó, chúng sẽ không khả dụng. Bạn có chắc chắn muốn tiếp tục không?",
"MoveToTrashTitle": "Chuyển đến thùng rác?",
"UnsubscribeButton": "Hủy đăng ký", "UnsubscribeButton": "Hủy đăng ký",
"UnsubscribeNote": "Bạn có chắc muốn hủy đăng ký các mục đã chọn từ danh sách không?", "UnsubscribeNote": "Bạn có chắc muốn hủy đăng ký các mục đã chọn từ danh sách không?",
"UnsubscribeTitle": "Xác nhận hủy đăng ký" "UnsubscribeTitle": "Xác nhận hủy đăng ký"

View File

@ -1,4 +1,5 @@
{ {
"DeleteUser": "Xoá người dùng", "DeleteUser": "Xoá người dùng",
"DeleteUserMessage": "{{userCaption}} <strong>{{user}}</strong> sẽ bị xóa. Tài liệu cá nhân của người dùng hữu dụng với người khác sẽ bị xóa. Bạn có chắc chắn muốn tiếp tục?",
"SuccessfullyDeleteUserInfoMessage": "Người dùng đã được xóa thành công" "SuccessfullyDeleteUserInfoMessage": "Người dùng đã được xóa thành công"
} }

View File

@ -1,3 +1,5 @@
{ {
"DisconnectCloudMessage": "Bạn có chắc chắn muốn xóa {{service}} không? Điều này sẽ không ảnh hưởng đến tài khoản {{account}} của bạn theo bất kỳ cách nào.",
"DisconnectCloudTitle": "Ngắt kết nối đám mây",
"SuccessDeleteThirdParty": "{{service}} bên thứ ba đã bị xóa" "SuccessDeleteThirdParty": "{{service}} bên thứ ba đã bị xóa"
} }

View File

@ -1,3 +1,5 @@
{ {
"DeleteGroupUsersSuccessMessage": "Người dùng đã được xóa thành công." "DeleteGroupUsersSuccessMessage": "Người dùng đã được xóa thành công.",
"DeleteUsers": "Xoá người dùng",
"DeleteUsersMessage": "Người dùng bị vô hiệu hóa đã chọn sẽ bị xóa khỏi DocSpace. Tài liệu cá nhân của những người dùng này hữu dụng cho người khác sẽ bị xóa."
} }

View File

@ -1,6 +1,8 @@
{ {
"DeleteForeverButton": "Xóa vĩnh viễn", "DeleteForeverButton": "Xóa vĩnh viễn",
"DeleteForeverNote": "Tất cả các mục từ Thùng rác sẽ bị xóa vĩnh viễn. Bạn sẽ không thể khôi phục chúng.", "DeleteForeverNote": "Tất cả các mục từ Thùng rác sẽ bị xóa vĩnh viễn. Bạn sẽ không thể khôi phục chúng.",
"DeleteForeverNoteArchive": "Tất cả các mục từ Sao Lưu sẽ bị xóa vĩnh viễn. Bạn sẽ không thể khôi phục chúng.",
"DeleteForeverTitle": "Xóa vĩnh viễn?", "DeleteForeverTitle": "Xóa vĩnh viễn?",
"SuccessEmptyArchived": "Đã xóa Sao lưu",
"SuccessEmptyTrash": "Đã dọn sạch thùng rác" "SuccessEmptyTrash": "Đã dọn sạch thùng rác"
} }

View File

@ -3,5 +3,6 @@
"Error403Text": " Xin lỗi, truy cập bị từ chối.", "Error403Text": " Xin lỗi, truy cập bị từ chối.",
"Error404Text": " Xin lỗi, không thể tìm thấy tài nguyên.", "Error404Text": " Xin lỗi, không thể tìm thấy tài nguyên.",
"ErrorEmptyResponse": "Không có hồi đáp", "ErrorEmptyResponse": "Không có hồi đáp",
"ErrorOfflineText": "Không tìm thấy kết nối internet" "ErrorOfflineText": "Không tìm thấy kết nối internet",
"ErrorUnavailableText": "DocSpace không khả dụng"
} }

View File

@ -1,33 +1,58 @@
{ {
"AddMembersDescription": "Bạn có thể thêm thành viên nhóm mới theo cách thủ công hoặc mời họ qua liên kết.",
"All": "Tất cả", "All": "Tất cả",
"AllFiles": "Tất cả các tệp", "AllFiles": "Tất cả các tệp",
"ArchiveAction": "Kho sao lưu trống",
"ArchiveEmptyScreen": "Bạn có thể sao lưu các phòng bạn không sử dụng và khôi phục chúng trong DocSpace của bạn bất cứ lúc nào hoặc xóa chúng vĩnh viễn. Những phòng này sẽ xuất hiện ở đây.",
"ArchiveEmptyScreenHeader": "Chưa có phòng sao lưu nào ở đây",
"ArchiveEmptyScreenUser": "Các phòng đã được sao lưu sẽ xuất hiện ở đây.",
"ArchivedRoomAction": "Phòng '{{name}}' đã được sao lưu",
"ArchivedRoomsAction": "Các phòng đã được sao lưu",
"Archives": "Lưu trữ", "Archives": "Lưu trữ",
"BackToParentFolderButton": "Quay lại thư mục gốc", "BackToParentFolderButton": "Quay lại thư mục gốc",
"ByAuthor": "Tác giả", "ByAuthor": "Tác giả",
"ByCreation": "Đã tạo", "ByCreation": "Đã tạo",
"ByErasure": "Xóa",
"ByLastModified": "Đã sửa đổi", "ByLastModified": "Đã sửa đổi",
"CollaborationRooms": "Cộng tác",
"ContainsSpecCharacter": "Tiêu đề không được chứa bất kỳ ký tự nào sau đây: *+:\"<>?|/", "ContainsSpecCharacter": "Tiêu đề không được chứa bất kỳ ký tự nào sau đây: *+:\"<>?|/",
"Convert": "Chuyển đổi", "Convert": "Chuyển đổi",
"CopyItem": "<strong>{{title}}</strong> đã sao chép ", "CopyItem": "<strong>{{title}}</strong> đã sao chép ",
"CopyItems": "<strong>{{qty}}</strong> thành phần được sao chép ", "CopyItems": "<strong>{{qty}}</strong> thành phần được sao chép ",
"CreateRoom": "Tạo phòng",
"CustomRooms": "Tùy chỉnh",
"DaysRemaining": "Số ngày còn lại: {{daysRemaining}}",
"DisableNotifications": "Tắt thông báo",
"Document": "Tài liệu", "Document": "Tài liệu",
"EditRoom": "Chỉnh sửa phòng",
"EmptyFile": "Tệp trống", "EmptyFile": "Tệp trống",
"EmptyFilterDescriptionText": "Không có tệp hoặc thư mục nào phù hợp với bộ lọc này. Hãy thử bộ lọc khác hoặc xóa bộ lọc để xem tất cả các tệp. ", "EmptyFilterDescriptionText": "Không có tệp hoặc thư mục nào phù hợp với bộ lọc này. Hãy thử bộ lọc khác hoặc xóa bộ lọc để xem tất cả các tệp. ",
"EmptyFilterSubheadingText": "Không có tệp nào được hiển thị cho bộ lọc này ở đây", "EmptyFilterSubheadingText": "Không có tệp nào được hiển thị cho bộ lọc này ở đây",
"EmptyFolderDecription": "Thả tập tin ở đây hoặc tạo tập tin mới", "EmptyFolderDecription": "Thả tập tin ở đây hoặc tạo tập tin mới",
"EmptyFolderDescriptionUser": "Các tập tin và thư mục được quản trị viên tải lên sẽ xuất hiện ở đây.",
"EmptyFolderHeader": "Không có tệp nào trong thư mục này", "EmptyFolderHeader": "Không có tệp nào trong thư mục này",
"EmptyRecycleBin": "Thùng rác trống", "EmptyRecycleBin": "Thùng rác trống",
"EmptyScreenFolder": "Chưa có tài liệu nào ở đây", "EmptyScreenFolder": "Chưa có tài liệu nào ở đây",
"EnableNotifications": "Bật thông báo",
"ExcludeSubfolders": "Loại trừ các thư mục con",
"FavoritesEmptyContainerDescription": "Để đánh dấu các tệp là tệp yêu thích hoặc xóa chúng khỏi danh sách này, hãy sử dụng menu thuộc tính.", "FavoritesEmptyContainerDescription": "Để đánh dấu các tệp là tệp yêu thích hoặc xóa chúng khỏi danh sách này, hãy sử dụng menu thuộc tính.",
"FileContents": "Nội dung tập tin",
"FileRemoved": "Đã chuyển tệp vào Thùng rác", "FileRemoved": "Đã chuyển tệp vào Thùng rác",
"FileRenamed": "Tài liệu {{oldTitle}} được đổi tên thành {{newTitle}}", "FileRenamed": "Tài liệu {{oldTitle}} được đổi tên thành {{newTitle}}",
"FillingFormRooms": "Điền biểu mẫu",
"Filter": "Bộ lọc", "Filter": "Bộ lọc",
"FinalizeVersion": "Hoàn thành phiên bản", "FinalizeVersion": "Hoàn thành phiên bản",
"Folder": "Thư mục", "Folder": "Thư mục",
"FolderRemoved": "Thư mục được chuyển vào Thùng rác", "FolderRemoved": "Thư mục được chuyển vào Thùng rác",
"FolderRenamed": "Thư mục {{folderTitle}}, được đổi tên thành {{newFoldedTitle}}", "FolderRenamed": "Thư mục {{folderTitle}}, được đổi tên thành {{newFoldedTitle}}",
"Forms": "Các Biểu mẫu",
"FormsTemplates": "Mẫu biểu mẫu",
"GoToMyRooms": "Vào Phòng của tôi",
"GoToPersonal": "Vào mục Tài liệu của tôi",
"Images": "Hình ảnh", "Images": "Hình ảnh",
"InviteUsersInRoom": "Mời người dùng vào phòng",
"LinkForPortalUsers": "Liên kết dành cho người dùng cổng thông tin", "LinkForPortalUsers": "Liên kết dành cho người dùng cổng thông tin",
"LinkForRoomMembers": "Liên kết cho các thành viên phòng",
"MarkAsFavorite": "Đánh dấu là yêu thích", "MarkAsFavorite": "Đánh dấu là yêu thích",
"MarkRead": "Đánh dấu là đã đọc", "MarkRead": "Đánh dấu là đã đọc",
"MarkedAsFavorite": "Đã thêm vào mục yêu thích", "MarkedAsFavorite": "Đã thêm vào mục yêu thích",
@ -36,10 +61,17 @@
"MoveItems": "<strong>{{qty}}</strong> thành phần đã được chuyển ", "MoveItems": "<strong>{{qty}}</strong> thành phần đã được chuyển ",
"MoveOrCopy": "Di chuyển hoặc Sao chép", "MoveOrCopy": "Di chuyển hoặc Sao chép",
"MoveTo": "Chuyển tới", "MoveTo": "Chuyển tới",
"MoveToArchive": "Di chuyển đến sao lưu",
"MoveToFolderMessage": "Bạn không thể chuyển thư mục sang thư mục con của nó", "MoveToFolderMessage": "Bạn không thể chuyển thư mục sang thư mục con của nó",
"New": "Mới", "New": "Mới",
"NewRoom": "Phòng mới",
"NoAccessRoomDescription": "Bạn sẽ được tự động chuyển hướng đến Phòng của tôi trong 5 giây.",
"NoAccessRoomTitle": "Rất tiếc, bạn không có quyền truy cập vào phòng này.",
"NoFilesHereYet": "Chưa có tập tin nào ở đây",
"Open": "Mở", "Open": "Mở",
"OpenLocation": "Vị trí mở", "OpenLocation": "Vị trí mở",
"Pin": "Ghim",
"PinToTop": "Ghim lên đầu trang",
"Presentation": "Bản trình bày", "Presentation": "Bản trình bày",
"PrivateRoomDescriptionEncrypted": "Chỉnh sửa được mã hóa và cùng làm việc trong thời gian thực.", "PrivateRoomDescriptionEncrypted": "Chỉnh sửa được mã hóa và cùng làm việc trong thời gian thực.",
"PrivateRoomDescriptionSafest": "Bộ nhớ an toàn nhất cho docx, xlsx và pptx.", "PrivateRoomDescriptionSafest": "Bộ nhớ an toàn nhất cho docx, xlsx và pptx.",
@ -47,10 +79,23 @@
"PrivateRoomDescriptionUnbreakable": "Thuật toán AES-256 không thể phá vỡ.", "PrivateRoomDescriptionUnbreakable": "Thuật toán AES-256 không thể phá vỡ.",
"PrivateRoomHeader": "Chào mừng bạn đến với phòng riêng ONLYOFFICE, nơi mọi ký hiệu bạn nhập đều được mã hóa", "PrivateRoomHeader": "Chào mừng bạn đến với phòng riêng ONLYOFFICE, nơi mọi ký hiệu bạn nhập đều được mã hóa",
"PrivateRoomSupport": "Làm việc trong Phòng Riêng có sẵn qua ứng dụng máy tính{{organizationName}} . <3>Hướng dẫn</3>", "PrivateRoomSupport": "Làm việc trong Phòng Riêng có sẵn qua ứng dụng máy tính{{organizationName}} . <3>Hướng dẫn</3>",
"RecentEmptyContainerDescription": "Tài liệu đã xem hoặc chỉnh sửa lần cuối của bạn sẽ được hiển thị trong phần này.",
"RecycleBinAction": "Xoá Sạch Thùng rác",
"RemoveFromFavorites": "Xóa khỏi danh sách yêu thích", "RemoveFromFavorites": "Xóa khỏi danh sách yêu thích",
"RemoveFromList": "Xóa khỏi danh sách", "RemoveFromList": "Xóa khỏi danh sách",
"RemovedFromFavorites": "Đã xóa khỏi mục yêu thích", "RemovedFromFavorites": "Đã xóa khỏi mục yêu thích",
"Rename": "Đổi tên", "Rename": "Đổi tên",
"RestoreAll": "Khôi phục tất cả",
"RoomCreated": "Đã tạo phòng",
"RoomEmptyContainerDescription": "Xin vui lòng tạo phòng đầu tiên.",
"RoomEmptyContainerDescriptionUser": "Các phòng được chia sẻ với bạn sẽ xuất hiện ở đây",
"RoomNotificationsDisabled": "Đã tắt thông báo phòng",
"RoomNotificationsEnabled": "Đã bật thông báo phòng",
"RoomPinned": "Phòng đã được ghim",
"RoomRemoved": "Đã xóa phòng",
"RoomUnpinned": "Phòng đã hủy ghim",
"RoomsRemoved": "Đã xóa phòng",
"SearchByContent": "Tìm kiếm theo nội dung tập tin",
"SendByEmail": "Gửi qua email", "SendByEmail": "Gửi qua email",
"Share": "Chia sẻ", "Share": "Chia sẻ",
"ShowVersionHistory": "Hiển thị lịch sử phiên bản", "ShowVersionHistory": "Hiển thị lịch sử phiên bản",
@ -59,9 +104,15 @@
"TooltipElementsCopyMessage": "Sao chép {{element}} thành phần", "TooltipElementsCopyMessage": "Sao chép {{element}} thành phần",
"TooltipElementsMoveMessage": "Di chuyển {{element}} thành phần", "TooltipElementsMoveMessage": "Di chuyển {{element}} thành phần",
"TrashEmptyDescription": "Phần 'Thùng rác' là nơi chứa tất cả các file đã xoá. Bạn có thể khôi phục chúng nếu là do xóa nhầm hoặc xóa bỏ chúng vĩnh viễn. Lưu ý rằng khi bạn xóa các file từ 'Thùng rác' chúng sẽ không thể được khôi phục lại.", "TrashEmptyDescription": "Phần 'Thùng rác' là nơi chứa tất cả các file đã xoá. Bạn có thể khôi phục chúng nếu là do xóa nhầm hoặc xóa bỏ chúng vĩnh viễn. Lưu ý rằng khi bạn xóa các file từ 'Thùng rác' chúng sẽ không thể được khôi phục lại.",
"TrashErasureWarning": "Các mục trong Thùng rác sẽ tự động bị xóa sau 30 ngày.",
"UnarchivedRoomAction": "Phòng '{{name}}' chưa được sao lưu.",
"UnarchivedRoomsAction": "Các phòng chưa được sao lưu.",
"UnblockVersion": "Bỏ chặn/Đăng ký", "UnblockVersion": "Bỏ chặn/Đăng ký",
"Unpin": "Bỏ ghim",
"VersionBadge": "V.{{version}}", "VersionBadge": "V.{{version}}",
"VersionHistory": "Lịch sử phiên bản", "VersionHistory": "Lịch sử phiên bản",
"ViewList": "Danh sách", "ViewList": "Danh sách",
"ViewTiles": "Ô xếp" "ViewOnlyRooms": "Chỉ xem",
"ViewTiles": "Ô xếp",
"WithSubfolders": "Với các thư mục con"
} }

View File

@ -1,4 +1,5 @@
{ {
"AdditionalSections": "Các phần bổ sung",
"ConnectEmpty": "Không có gì ở đây cả", "ConnectEmpty": "Không có gì ở đây cả",
"DisplayFavorites": "Hiển thị Yêu thích", "DisplayFavorites": "Hiển thị Yêu thích",
"DisplayNotification": "Hiển thị thông báo khi chuyển các mục vào Thùng rác", "DisplayNotification": "Hiển thị thông báo khi chuyển các mục vào Thùng rác",
@ -8,5 +9,8 @@
"KeepIntermediateVersion": "Giữ các phiên bản đã lưu trong quá trình chỉnh sửa", "KeepIntermediateVersion": "Giữ các phiên bản đã lưu trong quá trình chỉnh sửa",
"OriginalCopy": "Lưu cả bản sao của tệp ở định dạng gốc", "OriginalCopy": "Lưu cả bản sao của tệp ở định dạng gốc",
"StoringFileVersion": "Lưu trữ các phiên bản của tệp", "StoringFileVersion": "Lưu trữ các phiên bản của tệp",
"UpdateOrCreate": "Cập nhật phiên bản của tệp cho tệp hiện có với cùng tên. Nếu không, bản sao của tệp sẽ được tạo." "ThirdPartyAccounts": "Tài khoản của bên thứ ba",
"ThirdPartyBtn": "Cho phép kết nối kho lưu trữ của bên thứ ba",
"UpdateOrCreate": "Cập nhật phiên bản của tệp cho tệp hiện có với cùng tên. Nếu không, bản sao của tệp sẽ được tạo.",
"UploadPluginsHere": "Tải plugin lên tại đây"
} }

View File

@ -1,8 +1,41 @@
{ {
"AccountsEmptyScreenText": "Xem chi tiết người dùng tại đây",
"AndMoreLabel": "và <strong>{{count}} hơn thế nữa</strong>",
"CreationDate": "Ngày tạo",
"Data": "Dữ liệu",
"DateModified": "Ngày sửa đổi",
"FeedCreateFileSeveral": "Đã thêm tập tin",
"FeedCreateFileSingle": "Đã tạo tập tin",
"FeedCreateFolderSeveral": "Đã thêm thư mục",
"FeedCreateFolderSingle": "Đã tạo thư mục",
"FeedCreateRoom": "Đã tạo phòng <strong>«{{roomTitle}}»</strong>",
"FeedCreateRoomTag": "Đã thêm thẻ",
"FeedCreateUser": "Người dùng đã được thêm vào",
"FeedDeleteFile": "Đã xóa tập tin",
"FeedDeleteFolder": "Đã xóa thư mục",
"FeedDeleteRoomTag": "Đã xóa thẻ",
"FeedDeleteUser": "Người dùng đã bị xóa",
"FeedLocationLabel": "Thư mục «{{folderTitle}}»",
"FeedMoveFile": "Đã chuyển tập tin",
"FeedMoveFolder": "Đã di chuyển thư mục",
"FeedRenameFile": "Đã đổi tên tập tin",
"FeedRenameFolder": "Đã đổi tên thư mục",
"FeedRenameRoom": "Phòng <strong>«{{oldRoomTitle}}»</strong> đổi tên thành <strong>«{{roomTitle}}»</strong>.",
"FeedUpdateFile": "Đã cập nhật tập tin",
"FeedUpdateRoom": "Đã thay đổi biểu tượng",
"FeedUpdateUser": "đã được chỉ định vai trò {{role}}",
"FileExtension": "Phần mở rộng tập tin", "FileExtension": "Phần mở rộng tập tin",
"FilesEmptyScreenText": "Xem chi tiết tệp và thư mục tại đây", "FilesEmptyScreenText": "Xem chi tiết tệp và thư mục tại đây",
"ItemsSelected": "Các mục đã chọn", "ItemsSelected": "Các mục đã chọn",
"LastModifiedBy": "Sửa lần cuối bởi", "LastModifiedBy": "Sửa lần cuối bởi",
"PendingInvitations": "Thư mời chờ duyệt",
"Properties": "Thuộc tính",
"RoomsEmptyScreenTent": "Xem chi tiết phòng tại đây",
"SelectedUsers": "Tài khoản đã chọn",
"StorageType": "Kiểu lưu trữ",
"SubmenuDetails": "Chi tiết",
"SubmenuHistory": "Lịch sử",
"SystemProperties": "Thuộc tính hệ thống", "SystemProperties": "Thuộc tính hệ thống",
"UsersInRoom": "Người dùng trong phòng",
"Versions": "Phiên Bản" "Versions": "Phiên Bản"
} }

View File

@ -1,3 +1,14 @@
{ {
"LinkCopySuccess": "Liên kết đã được sao chép" "AddManually": "Thêm vào một cách thủ công",
"AddManuallyDescriptionAccounts": "Mời người dùng mới vào DocSpace cá nhân qua email",
"AddManuallyDescriptionRoom": "Thêm người dùng DocSpace hiện có vào phòng bằng cách sử dụng tên hoặc mời người dùng mới qua email",
"EmailErrorMessage": "Địa chỉ Email không hợp lệ. Bạn có thể chỉnh sửa email bằng cách nhấp vào nó.",
"InviteAccountSearchPlaceholder": "Mời người dùng qua email",
"InviteRoomSearchPlaceholder": "Mời người dùng theo tên hoặc email",
"InviteViaLink": "Mời qua liên kết",
"InviteViaLinkDescriptionAccounts": "Tạo một liên kết universal link để tự ủy quyền trong DocSpace",
"InviteViaLinkDescriptionRoom": "Tạo một liên kết universal link để tự ủy quyền trong phòng",
"Invited": "Đã mời",
"LinkCopySuccess": "Liên kết đã được sao chép",
"SendInvitation": "Gửi lời mời"
} }

View File

@ -3,17 +3,17 @@
"CopyWindowCode": "Sao chép mã nhúng cửa sổ", "CopyWindowCode": "Sao chép mã nhúng cửa sổ",
"DataDisplay": "Cài đặt hiển thị dữ liệu", "DataDisplay": "Cài đặt hiển thị dữ liệu",
"Descending": "Giảm dần", "Descending": "Giảm dần",
"Destroy": "Hủy hoại", "Destroy": "Xóa hủy",
"EnterCount": "Nhập số lượng", "EnterCount": "Nhập số lượng",
"EnterHeight": "Nhập chiều cao", "EnterHeight": "Nhập chiều cao",
"EnterId": "Nhập ID", "EnterId": "Nhập id",
"EnterPage": "Nhập số trang", "EnterPage": "Nhập số trang",
"EnterWidth": "Nhập chiều rộng", "EnterWidth": "Nhập chiều rộng",
"FolderId": "ID thư mục", "FolderId": "Id thư mục",
"FrameId": "Id khung", "FrameId": "Id khung",
"Header": "Tiêu đề", "Header": "Tiêu đề",
"ItemsCount": "Số lượng mặt hàng", "ItemsCount": "Số lượng mục",
"JavascriptSdk": "Sdk Javascript", "JavascriptSdk": "Javascript sdk",
"Menu": "Thực đơn", "Menu": "Thực đơn",
"Page": "Trắng", "Page": "Trắng",
"SearchTerm": "Cụm từ tìm kiếm", "SearchTerm": "Cụm từ tìm kiếm",

View File

@ -1 +1,14 @@
{} {
"ClickHere": "Nhấp vào đây",
"ConfirmEmailDescription": "Sử dụng liên kết được cung cấp trong email kích hoạt. Bạn chưa nhận được email chứa liên kết kích hoạt?",
"ConfirmEmailHeader": "Xin vui lòng kích hoạt email ({{ email }}) của bạn để có quyền truy cập vào các tính năng DocSpace.",
"RequestActivation": "Yêu cầu kích hoạt lại",
"RoomQuotaDescription": "Bạn có thể sao lưu các phòng không cần thiết hoặc <1>{{clickHere}}</1> để tìm gói dịch vụ có giá phù hợp hơn cho DocSpace của mình.",
"RoomQuotaHeader": "Phòng sắp vượt quá:{{currentValue}} / {{maxValue}}",
"StorageAndRoomHeader": "Sắp vượt quá giới hạn lưu trữ và phòng.",
"StorageAndUserHeader": "Sắp vượt quá giới hạn lưu trữ và quản trị viên/người dùng cấp cao.",
"StorageQuotaDescription": "Bạn có thể xóa các tập tin không cần thiết hoặc <1>{{clickHere}}</1> để tìm gói dịch vụ có giá phù hợp hơn cho DocSpace của mình.",
"StorageQuotaHeader": "Dung lượng lưu trữ sắp vượt quá:{{currentValue}} / {{maxValue}}",
"UserQuotaDescription": "<1>{{clickHere}}</1> để tìm gói dịch vụ có giá tốt hơn cho DocSpace của bạn.",
"UserQuotaHeader": "Sắp vượt quá số lượng quản trị viên/người dùng cấp cao:{{currentValue}}/{{maxValue}}."
}

View File

@ -1 +1,13 @@
{} {
"ActionsWithFilesDescription": "Huy hiệu sẽ thông báo cho bạn về các hành động như tải lên, tạo và thay đổi trong tập tin.",
"Badges": "Danh hiệu",
"DailyFeed": "Nguồn cấp dữ liệu DocSpace hàng ngày",
"DailyFeedDescription": "Đọc tin và sự kiện từ DocSpace của bạn trong một bản tóm tắt hàng ngày.",
"ManageNotifications": "Quản lý",
"Notifications": "Thông báo",
"RoomsActions": "Hành động với các tập tin trong Phòng",
"RoomsActivity": "Hoạt động phòng",
"RoomsActivityDescription": "Thông báo hàng giờ. Luôn cập nhật về tất cả các hoạt động trong phòng của bạn.",
"UsefulTips": "Các mẹo hữu ích sử dụng DocSpace",
"UsefulTipsDescription": "Nhận hướng dẫn hữu ích về DocSpace"
}

View File

@ -1 +1,43 @@
{} {
"AccessingProblem": "Nếu bạn hiện là người dùng và gặp sự cố khi truy cập không gian này, xin vui lòng liên hệ với quản trị viên.",
"AdministratorDescription": "Đặt cấu hình DocSpace, tạo phòng và quản trị, khả năng mời và quản lý người dùng trong DocSpace và trong phòng ảo, khả năng quản lý quyền truy cập.",
"Benefits": "Lợi ích",
"BusinessExpired": "Gói dịch vụ {{planName}} của bạn đã hết hạn vào ngày {{date}}",
"BusinessFinalDateInfo": "Gói dịch vụ đăng ký sẽ được tự động gia hạn vào ngày {{finalDate}} với mức phí và tính năng được cập nhật. Bạn có thể hủy nó hoặc thay đổi thông tin thanh toán của bạn trên cổng thông tin khách hàng Stripe của bạn.",
"BusinessPlanPaymentOverdue": "Không thể thêm người dùng mới và tạo phòng mới. Quá hạn thanh toán cho gói dịch vụ {{planName}}.",
"BusinessRequestDescription": "Các gói dịch vụ với thêm {{peopleNumber}} quản trị viên/người dùng cấp cao chỉ có theo yêu cầu.",
"BusinessSuggestion": "Tùy chỉnh gói dịch vụ {{planName}} của bạn",
"BusinessTitle": "Bạn đang sử dụng gói dịch vụ {{planName}}",
"BusinessUpdated": "Đã cập nhật gói dịch vụ {{planName}}",
"ChooseNewPayer": "Chọn Người thanh toán mới",
"ChooseNewPlan": "Bạn có muốn chọn gói dịch vụ có giá mới không?",
"ContactUs": "Đối với câu hỏi về việc bán hàng, xin hãy liên hệ với chúng tôi tại",
"DelayedPayment": "Chậm thanh toán gói kế hoạch {{planName}} {{date}} ngày",
"DowngradeNow": "Hạ cấp ngay",
"ErrorNotification": "Không thể cập nhật bảng phí cho gói dịch vụ. Hãy thử lại sau hoặc liên hệ với bộ phận kinh doanh.",
"GracePeriodActivatedDescription": "Trong thời gian ân hạn, quản trị viên không thể tạo phòng mới và thêm người dùng mới. Sau ngày hết hạn thanh toán của thời gian ân hạn, DocSpace sẽ không khả dụng cho đến khi thanh toán được thực hiện.",
"GracePeriodActivatedInfo": "Thời gian gia hạn có hiệu lực <1>từ {{fromDate}} đến {{byDate}}</1> (số ngày còn: {{delayDaysCount}}).",
"InvalidEmailWithActiveSubscription": "Gói dịch vụ đăng ký của bạn vẫn hiệu lực, nhưng chúng tôi khuyên bạn nên chọn một Người trả phí mới có quyền truy cập vào cài đặt đăng ký trong DocSpace.",
"InvalidEmailWithActiveSubscriptionForAdmin": "Gói dịch vụ đăng ký của bạn vẫn hiệu lực, nhưng chúng tôi khuyên bạn nên liên hệ với chủ sở hữu DocSpace để chọn Người trả phí mới.",
"InvalidEmailWithoutActiveSubscription": "Chúng tôi khuyên bạn nên chọn một Người trả phí mới có quyền truy cập vào cài đặt đăng ký trong DocSpace.",
"InvalidEmailWithoutActiveSubscriptionByAdmin": "Chúng tôi khuyên bạn nên liên hệ với chủ sở hữu DocSpace để chọn Người trả phí mới.",
"ManagerTypesDescription": "Các loại tài khoản quản trị và đặc quyền của chúng",
"Pay": "Thanh toán",
"Payer": "Người thanh toán",
"PayerDescription": "Người dùng này có quyền truy cập vào thông tin thanh toán và là người dùng duy nhất có thể điều chỉnh định mức và thực hiện thanh toán. Chủ sở hữu DocSpace, cũng như chính người quản lý thanh toán, có thể chỉ định lại vai trò người quản lý thanh toán bằng cổng thông tin khách hàng Stripe.",
"PaymentOverdue": "Không thể thêm người dùng mới.",
"PriceCalculation": "Tính phí của bạn",
"QuotaPaidUserLimitError": "Đã đạt đến giới hạn người dùng trả phí. <1>Thanh toán</1>",
"RenewSubscription": "Gia hạn gói dịch vụ {{planName}}",
"RoomManagerDescription": "Quản trị và lưu trữ phòng, mời và quản lý người dùng. Một số quản trị viên có thể được chỉ định vào phòng.",
"StartupSuggestion": "Làm nhiều hơn với gói dịch vụ {{planName}}",
"StartupTitle": "Bạn đang sử dụng gói dịch vụ {{planName}} miễn phí",
"StripeCustomerPortal": "truy cập cổng thông tin khách hàng trên Stripe",
"TotalPricePerMonth": "<1>{{currencySymbol}} </1><2>{{price}} </2><3>/tháng</3>",
"UpgradeNow": "Nâng cấp ngay",
"UpgradePlan": "Nâng cấp gói dịch vụ",
"UpgradePlanInfo": "Việc thêm người dùng mới sẽ vượt quá số lượng thành viên tối đa được phép trong phòng theo gói dịch vụ hiện tại của bạn.",
"UserNotFound": "Không tìm thấy người dùng<1>{{email}}</1>.",
"UserNotFoundMatchingEmail": "Chúng tôi không thể tìm thấy người dùng có e-mail Stripe phù hợp.",
"YourPrice": "Phí thanh toán của bạn"
}

View File

@ -1,5 +1,7 @@
{ {
"LblInviteAgain": "Mời lại", "LblInviteAgain": "Mời lại",
"MessageEmailActivationInstuctionsSentOnEmail": "Email hướng dẫn kích hoạt đã được gửi đến địa chỉ email <1>{{email}}</1>.", "MessageEmailActivationInstuctionsSentOnEmail": "Email hướng dẫn kích hoạt đã được gửi đến địa chỉ email <1>{{email}}</1>.",
"NotFoundUsers": "Không tìm thấy người dùng",
"NotFoundUsersDescription": "Không có người phù hợp với bộ lọc của bạn để hiển thị. Xin vui lòng chọn các tùy chọn bộ lọc khác hoặc xóa bộ lọc để xem tất cả những người trong phần này.",
"UserStatus": "Trạng thái" "UserStatus": "Trạng thái"
} }

View File

@ -1 +1,7 @@
{} {
"AllAccounts": "Tất cả tài khoản",
"EmptyDescription": "Danh sách người dùng trước đây được mời đến DocSpace hoặc các phòng riêng biệt sẽ xuất hiện ở đây. Bạn sẽ có thể mời những người dùng này cộng tác bất cứ lúc nào.",
"EmptyHeader": "Chưa có tài khoản nào khác ở đây",
"ListAccounts": "Liệt kê tài khoản",
"SearchEmptyDescription": "Không có người nào phù hợp với bộ lọc của bạn có thể được hiển thị trong phần này. Xin vui lòng chọn các tùy chọn bộ lọc khác hoặc xóa bộ lọc để xem tất cả những người trong phần này."
}

View File

@ -6,11 +6,14 @@
"EnableUserButton": "Kích hoạt", "EnableUserButton": "Kích hoạt",
"InviteLinkTitle": "Liên kết mời", "InviteLinkTitle": "Liên kết mời",
"LDAPLbl": "LDAP", "LDAPLbl": "LDAP",
"NameChangeButton": "Đổi tên",
"PasswordChangeButton": "Thay đổi mật khẩu", "PasswordChangeButton": "Thay đổi mật khẩu",
"PendingTitle": "Đang chờ xử lý", "PendingTitle": "Đang chờ xử lý",
"RemoveData": "Xóa dữ liệu cá nhân", "RemoveData": "Xóa dữ liệu cá nhân",
"ResetAuth": "Đặt lại xác thực",
"SendInviteAgain": "Gửi lại lời mời", "SendInviteAgain": "Gửi lại lời mời",
"SuccessChangeUserStatus": "Trạng thái người dùng đã được thay đổi thành công", "SuccessChangeUserStatus": "Trạng thái người dùng đã được thay đổi thành công",
"SuccessDeletePersonalData": "Dữ liệu cá nhân đã được xóa thành công", "SuccessDeletePersonalData": "Dữ liệu cá nhân đã được xóa thành công",
"SuccessSentInvitation": "Lời mời đã được gửi thành công" "SuccessSentInvitation": "Lời mời đã được gửi thành công",
"SuccessSentMultipleInvitatios": "Lời mời đã được gửi thành công"
} }

View File

@ -1 +1,4 @@
{} {
"AccessingProblem": "Nếu bạn gặp sự cố khi truy cập DocSpace này, xin vui lòng liên hệ với quản trị viên.",
"ContactAdministrator": "Liên hệ với quản trị viên DocSpace"
}

View File

@ -1,13 +1,29 @@
{ {
"ActiveSessions": "Các phiên Hoạt động",
"ChangeEmailSuccess": "Email đã được thay đổi thành công", "ChangeEmailSuccess": "Email đã được thay đổi thành công",
"ChangePasswordAfterLoggingOut": "Thay đổi mật khẩu sau khi đăng xuất",
"ConnectSocialNetworks": "Kết nối mạng xã hội của bạn",
"DarkTheme": "Nền tối", "DarkTheme": "Nền tối",
"DescriptionForSecurity": "Để bảo mật hơn, bạn cần thay đổi mật khẩu của mình.",
"EditPhoto": "Chỉnh sửa ảnh", "EditPhoto": "Chỉnh sửa ảnh",
"EmailNotVerified": "Email chưa được xác minh",
"InterfaceTheme": "Chủ đề giao diện\"", "InterfaceTheme": "Chủ đề giao diện\"",
"LightTheme": "Nền sáng", "LightTheme": "Nền sáng",
"LogoutActiveConnection": "Đăng xuất khỏi kết nối đang hoạt động",
"LogoutAllActiveConnections": "Đăng xuất khỏi tất cả các kết nối đang hoạt động",
"LogoutAllActiveSessions": "Đăng xuất khỏi tất cả các phiên hoạt động",
"LogoutAllActiveSessionsDescription": "Tất cả các kết nối đang hoạt động ngoại trừ kết nối này sẽ được đăng xuất, vì nó hiện đang được sử dụng.",
"LogoutBtn": "Đăng xuất",
"LogoutDescription": "Lưu ý. Tất cả các kết nối đang hoạt động ngoại trừ kết nối này sẽ được đăng xuất, vì nó hiện đang được sử dụng.",
"LogoutFrom": "Đăng xuất khỏi {{platform}} {{browser}}?",
"MyProfile": "Hồ sơ của tôi",
"ProviderSuccessfullyConnected": "Đã kết nối nhà cung cấp thành công", "ProviderSuccessfullyConnected": "Đã kết nối nhà cung cấp thành công",
"ProviderSuccessfullyDisconnected": " Đã ngắt kết nối nhà cung cấp thành công", "ProviderSuccessfullyDisconnected": " Đã ngắt kết nối nhà cung cấp thành công",
"SendAgain": "Gửi lại",
"ShowBackupCodes": "Hiển thị mã dự phòng", "ShowBackupCodes": "Hiển thị mã dự phòng",
"SuccessLogout": "Kết nối hoạt động đã được đăng xuất: {{platform}}, {{browser}}",
"SystemTheme": "Sử dụng chủ đề hệ thống", "SystemTheme": "Sử dụng chủ đề hệ thống",
"SystemThemeDescription": "Tự động chuyển đổi giữa các chế độ sáng và tối khi hệ thống của bạn hoạt động.",
"TfaLoginSettings": "Thiết lập đăng nhập ", "TfaLoginSettings": "Thiết lập đăng nhập ",
"TwoFactorDescription": " Xác thực hai yếu tố qua ứng dụng tạo mã đã được quản trị viên bật cho tất cả người dùng." "TwoFactorDescription": " Xác thực hai yếu tố qua ứng dụng tạo mã đã được quản trị viên bật cho tất cả người dùng."
} }

View File

@ -1,4 +1,5 @@
{ {
"ResetApplicationDescription": " Cấu hình ứng dụng Trình xác thực sẽ được đặt lại.", "ResetApplicationDescription": " Cấu hình ứng dụng Trình xác thực sẽ được đặt lại.",
"ResetApplicationTitle": " Đặt lại cấu hình ứng dụng" "ResetApplicationTitle": " Đặt lại cấu hình ứng dụng",
"SuccessResetApplication": "Cài đặt ứng dụng cho việc xác thực đã được đặt lại thành công."
} }

View File

@ -1 +1,5 @@
{} {
"EmptyRoomsDescription": "Xin vui lòng tạo phòng đầu tiên trong Phòng của Tôi.",
"EmptyRoomsHeader": "Chưa có phòng nào ở đây",
"RoomList": "Danh sách phòng"
}

View File

@ -1 +1,7 @@
{} {
"RequestDetails": "Xin vui lòng mô tả chi tiết yêu cầu của bạn tại đây.",
"SalesDepartmentRequest": "Yêu cầu phòng kinh doanh",
"SuccessfullySentMessage": "Tin nhắn của bạn đã được gửi đi thành công. Bộ phận Kinh doanh sẽ liên hệ với bạn.",
"YouWillBeContacted": "Đội ngũ kinh doanh sẽ liên hệ với bạn sau khi bạn gửi yêu cầu.",
"YourName": "Tên của bạn"
}

View File

@ -1,12 +1,29 @@
{ {
"AccentColor": "Nhấn mạnh",
"AccessRightsAccessToProduct": "Quyền truy cập vào mô-đun {{product}} được cấp cho", "AccessRightsAccessToProduct": "Quyền truy cập vào mô-đun {{product}} được cấp cho",
"AccessRightsAllUsers": "Tất cả {{users}}", "AccessRightsAllUsers": "Tất cả {{users}}",
"AccessRightsChangeOwnerConfirmText": "Các thay đổi sẽ được áp dụng sau khi xác nhận qua email.", "AccessRightsChangeOwnerConfirmText": "Các thay đổi sẽ được áp dụng sau khi xác nhận qua email.",
"AccessRightsProductUsersCan": "người dùng {{category}} có thể ", "AccessRightsProductUsersCan": "người dùng {{category}} có thể ",
"AccessRightsUsersFromList": "{{users}} từ danh sách ", "AccessRightsUsersFromList": "{{users}} từ danh sách ",
"AddAllowedIP": "Thêm địa chỉ IP được phép",
"AddTrustedDomain": "Thêm tên miền được tin cậy", "AddTrustedDomain": "Thêm tên miền được tin cậy",
"AdditionalResources": "Nguồn Thông tin Bổ sung",
"AdditionalResourcesDescription": "Chọn xem bạn có muốn hiển thị liên kết đến các tài nguyên bổ sung trong menu DocSpace hay không.",
"Admins": "Quản trị viên", "Admins": "Quản trị viên",
"AdminsMessage": "Cài đặt Tin nhắn Quản trị viên",
"AdminsMessageDescription": "Cài đặt Tin nhắn Quản trị viên là một cách để liên hệ với quản trị viên DocSpace.",
"AdminsMessageHelper": "Bật tùy chọn này để hiển thị biểu mẫu liên hệ trên trang Đăng nhập để mọi người có thể gửi tin nhắn cho quản trị viên trong trường hợp họ gặp sự cố khi truy cập DocSpace của bạn.",
"AllDomains": "Tên miền bất kỳ", "AllDomains": "Tên miền bất kỳ",
"AmazonBucketTip": "Nhập tên riêng của Amazon bucket S3 nơi bạn muốn lưu trữ các bản sao lưu của mình.",
"AmazonCSE": "Mã hóa phía máy khách",
"AmazonForcePathStyleTip": "Nếu là true, các yêu cầu sẽ luôn sử dụng địa chỉ kiểu đường dẫn.",
"AmazonHTTPTip": "Nếu thuộc tính này được đặt thành true, máy khách sẽ cố gắng sử dụng giao thức HTTP, nếu điểm cuối đích hỗ trợ nó. Theo mặc định, thuộc tính này được đặt thành false.",
"AmazonRegionTip": "Nhập vùng AWS nơi Amazon bucket của bạn lưu trú.",
"AmazonSSE": "Mã hóa phía máy chủ",
"AmazonSSETip": "Thuật toán mã hóa phía máy chủ được sử dụng khi lưu trữ đối tượng này trong S3.",
"AmazonServiceTip": "Đây là một thuộc tính tùy chọn; chỉ thay đổi nó nếu bạn muốn thử một điểm cuối dịch vụ khác",
"Appearance": "Hình thức",
"AuditSubheader": "Phần phụ cho phép bạn duyệt qua danh sách các thay đổi mới nhất (tạo, sửa đổi, xóa, v.v.) do người dùng thực hiện đối với các thực thể (phòng, cơ hội, tập tin, v.v.) trong DocSpace của bạn.",
"AuditTrailNav": "Kiểm tra Truy nguyên", "AuditTrailNav": "Kiểm tra Truy nguyên",
"AutoBackup": "Tự động sao lưu", "AutoBackup": "Tự động sao lưu",
"AutoBackupDescription": "Sử dụng tùy chọn này để tự động sao lưu dữ liệu cổng thông tin.", "AutoBackupDescription": "Sử dụng tùy chọn này để tự động sao lưu dữ liệu cổng thông tin.",
@ -19,12 +36,21 @@
"BackupCreatedSuccess": "Bản sao lưu đã được tạo thành công.", "BackupCreatedSuccess": "Bản sao lưu đã được tạo thành công.",
"BackupList": "Danh sách sao lưu", "BackupList": "Danh sách sao lưu",
"BackupListWarningText": "Nếu bạn xóa bất kỳ mục nào trong danh sách, các file tương ứng của chúng cũng sẽ bị xóa. Tác vụ này không thể được hoàn tác. Để xóa tất cả các file này sử dụng liên kết:", "BackupListWarningText": "Nếu bạn xóa bất kỳ mục nào trong danh sách, các file tương ứng của chúng cũng sẽ bị xóa. Tác vụ này không thể được hoàn tác. Để xóa tất cả các file này sử dụng liên kết:",
"Branding": "Thương hiệu",
"BrandingSectionDescription": "Nêu rõ thông tin công ty của bạn, thêm liên kết đến tài nguyên bên ngoài và địa chỉ email được hiển thị trong giao diện DocSpace.",
"BrandingSubtitle": "Sử dụng tùy chọn này để cung cấp trải nghiệm thương hiệu cho người dùng.",
"BreakpointWarningText": "Phần này chỉ có trong phiên bản máy tính để bàn",
"BreakpointWarningTextPrompt": "Xin vui lòng sử dụng trang web trên máy tính để truy cập cài đặt <1>{{sectionName}}</1>.",
"ButtonsColor": "Nút",
"ByApp": "Bằng ứng dụng trình xác thực", "ByApp": "Bằng ứng dụng trình xác thực",
"BySms": "Bằng sms", "BySms": "Bằng sms",
"ChangeLogoButton": "Thay đổi Logo", "ChangeLogoButton": "Thay đổi Logo",
"Characters": "{{length}} ký tự", "Characters": "{{length}} ký tự",
"ClearBackupList": "Xóa tất cả bản sao lưu", "ClearBackupList": "Xóa tất cả bản sao lưu",
"CompanyInfoSettings": "Cài đặt thông tin công ty",
"CompanyInfoSettingsDescription": "Thông tin này sẽ được hiển thị trong cửa sổ <1>{{link}}</1>.",
"ConfirmEmailSended": "Email xác nhận đã được gửi tới {{ownerName}}", "ConfirmEmailSended": "Email xác nhận đã được gửi tới {{ownerName}}",
"Custom": "Tùy chỉnh",
"CustomDomains": "Tùy chỉnh tên miền", "CustomDomains": "Tùy chỉnh tên miền",
"CustomTitles": "Tiêu đề tùy chỉnh", "CustomTitles": "Tiêu đề tùy chỉnh",
"CustomTitlesFrom": "Từ", "CustomTitlesFrom": "Từ",
@ -35,9 +61,26 @@
"CustomTitlesWelcome": "Thiết Lập Trang Chào Mừng", "CustomTitlesWelcome": "Thiết Lập Trang Chào Mừng",
"Customization": "Tùy chỉnh", "Customization": "Tùy chỉnh",
"CustomizationDescription": "Tiểu mục này cho phép bạn thay đổi giao diện của cổng thông tin của mình. Bạn có thể sử dụng logo, tên và văn bản của công ty để phù hợp với thương hiệu của tổ chức của bạn.", "CustomizationDescription": "Tiểu mục này cho phép bạn thay đổi giao diện của cổng thông tin của mình. Bạn có thể sử dụng logo, tên và văn bản của công ty để phù hợp với thương hiệu của tổ chức của bạn.",
"DNSSettings": "Thiết lập DNS",
"DNSSettingsDescription": "Thiết lập DNS là một cách để thiết lập một URL thay thế cho không gian của bạn.",
"DNSSettingsMobile": "Gửi yêu cầu của bạn đến nhóm hỗ trợ của chúng tôi và các chuyên gia của chúng tôi sẽ giúp bạn cài đặt.",
"DNSSettingsTooltip": "Thiết lập DNS cho phép bạn đặt địa chỉ URL thay thế cho không gian {{ organizationName }} của mình. Gửi yêu cầu của bạn đến nhóm hỗ trợ của chúng tôi và các chuyên gia của chúng tôi sẽ giúp bạn cài đặt.",
"DataBackup": "Sao lưu dữ liệu",
"Deactivate": "Vô hiệu hóa",
"DeactivateOrDeletePortal": "Tắt hoặc xóa cổng thông tin.", "DeactivateOrDeletePortal": "Tắt hoặc xóa cổng thông tin.",
"DeleteDocSpace": "Xóa DocSpace",
"DeleteDocSpaceInfo": "Trước khi bạn xóa không gian, xin vui lòng đảm bảo rằng thanh toán tự động đã được tắt. Bạn có thể kiểm tra trạng thái thanh toán tự động trong <1> cổng thông tin khách hàng Stripe của mình</1>.",
"DeleteTheme": "Xóa theme",
"DeleteThemeForever": "Xóa theme vĩnh viễn?",
"DeleteThemeNotice": "Theme sẽ bị xóa vĩnh viễn. Bạn sẽ không thể hoàn tác thao tác này.",
"DeveloperTools": "Công cụ nhà phát triển",
"Disabled": "Đã vô hiệu hóa", "Disabled": "Đã vô hiệu hóa",
"DownloadCopy": "Tải xuống bản sao", "DownloadCopy": "Tải xuống bản sao",
"DownloadReportBtnText": "Tải báo cáo xuống",
"DownloadReportDescription": "Báo cáo sẽ được lưu vào Tài liệu Của tôi",
"DownloadStatisticsText": "Bạn có thể tải xuống báo cáo cho dữ liệu hữu dụng trong thời gian lưu trữ đã chọn để xem số liệu thống kê chi tiết.",
"EditColorScheme": "Chỉnh sửa bảng màu",
"EditCurrentTheme": "Chỉnh sửa theme hiện tại",
"Employees": "người dùng", "Employees": "người dùng",
"EmptyBackupList": "Chưa có bản sao lưu nào được tạo. Tạo một hoặc nhiều bản sao lưu để chúng xuất hiện trong danh sách này.", "EmptyBackupList": "Chưa có bản sao lưu nào được tạo. Tạo một hoặc nhiều bản sao lưu để chúng xuất hiện trong danh sách này.",
"EnableAutomaticBackup": "Bật sao lưu tự động.", "EnableAutomaticBackup": "Bật sao lưu tự động.",
@ -47,14 +90,26 @@
"EveryMonth": "Hàng tháng", "EveryMonth": "Hàng tháng",
"EveryWeek": "Hàng tuần", "EveryWeek": "Hàng tuần",
"ForcePathStyle": "Kiểu đường dẫn bắt buộc", "ForcePathStyle": "Kiểu đường dẫn bắt buộc",
"IPSecurity": "Bảo mật IP",
"IPSecurityDescription": "Bảo mật IP được sử dụng để hạn chế đăng nhập vào không gian từ tất cả các địa chỉ IP ngoại trừ một số địa chỉ nhất định.",
"IPSecurityHelper": "Bạn có thể đặt các địa chỉ IP được phép bằng cách sử dụng địa chỉ IP chính xác ở định dạng IPv4 (#.#.#.#, trong đó # là giá trị số từ 0 đến 255) hoặc dải IP (trong định dạng #.#.#.#-#.#.#.#).",
"IPSecurityWarningHelper": "Trước tiên, bạn cần chỉ định IP hiện tại hoặc dải IP mà địa chỉ IP hiện tại của bạn thuộc về, nếu không quyền truy cập không gian của bạn sẽ bị chặn ngay sau khi bạn lưu cài đặt. Chủ sở hữu không gian sẽ có quyền truy cập không gian từ bất kỳ địa chỉ IP nào.",
"LanguageAndTimeZoneSettingsDescription": "Thay đổi ngôn ngữ cho tất cả người dùng cổng thông tin và định cấu hình múi giờ để tất cả các sự kiện cổng thông tin được hiển thị với ngày và giờ chính xác.", "LanguageAndTimeZoneSettingsDescription": "Thay đổi ngôn ngữ cho tất cả người dùng cổng thông tin và định cấu hình múi giờ để tất cả các sự kiện cổng thông tin được hiển thị với ngày và giờ chính xác.",
"LanguageTimeSettingsTooltip": "<0>{{text}}</0> cho phép thay đổi ngôn ngữ của toàn bộ cổng thông tin cho tất cả người dùng cổng và cấu hình múi giờ để tất cả các sự kiện trong cổng {{organizationName}} thông tin sẽ được hiển thị dưới dạng ngày và giờ chính xác.", "LanguageTimeSettingsTooltip": "<0>{{text}}</0> cho phép thay đổi ngôn ngữ của toàn bộ cổng thông tin cho tất cả người dùng cổng và cấu hình múi giờ để tất cả các sự kiện trong cổng {{organizationName}} thông tin sẽ được hiển thị dưới dạng ngày và giờ chính xác.",
"LanguageTimeSettingsTooltipDescription": "Để các thông số bạn thiết lập có hiệu lực, bấm vào nút <1>{{save}}</1> ở dưới cuối phần này.<3>{{learnMore}}</3>", "LanguageTimeSettingsTooltipDescription": "Để các thông số bạn thiết lập có hiệu lực, bấm vào nút <1>{{save}}</1> ở dưới cuối phần này.<3>{{learnMore}}</3>",
"Lifetime": "Thời gian tồn tại (phút)",
"LimitThemesTooltip": "Bạn chỉ có thể tạo 3 theme tùy chỉnh. Để tạo một theme mới, bạn phải xóa một trong các theme trước đó.",
"LocalFile": "Tập tin cục bộ", "LocalFile": "Tập tin cục bộ",
"LoginHistoryTitle": "Lịch sử đăng nhập", "LoginHistoryTitle": "Lịch sử đăng nhập",
"LoginLatestText": "Chỉ hoạt động mới nhất được hiển thị trên trang này. Bản thân dữ liệu được lưu trữ trong khoảng thời gian được nêu trong trường bên dưới (tối đa 180 ngày).",
"LoginSubheaderTitle": "Phần phụ này được sử dụng để theo dõi hoạt động đăng nhập mới nhất của người dùng bao gồm đăng nhập thành công và các lần cố đăng nhập không thành công với thông tin nguyên nhân.",
"LogoAbout": "Logo cho trang Giới thiệu",
"LogoCompact": "Logo cho menu nhỏ gọn bên trái",
"LogoDocsEditor": "Logo cho tiêu đề trình chỉnh sửa", "LogoDocsEditor": "Logo cho tiêu đề trình chỉnh sửa",
"LogoDocsEditorEmbedded": "Logo cho tiêu đề của biên tập viên - chế độ nhúng",
"LogoFavicon": "Favicon", "LogoFavicon": "Favicon",
"LogoLightSmall": "Logo cho tiêu đề cổng thông tin", "LogoLightSmall": "Logo cho tiêu đề cổng thông tin",
"LogoLogin": "Logo cho trang Đăng nhập và email",
"ManagementCategoryDataManagement": "Quản lý dữ liệu", "ManagementCategoryDataManagement": "Quản lý dữ liệu",
"ManagementCategoryIntegration": "Tích hợp", "ManagementCategoryIntegration": "Tích hợp",
"ManagementCategorySecurity": "Bảo mật", "ManagementCategorySecurity": "Bảo mật",
@ -62,12 +117,22 @@
"ManualBackupHelp": "Tùy chọn <strong>Sao lưu dữ liệu</strong> được sử dụng để sao lưu dữ liệu hệ thống để sau đó khôi phục tới máy chủ cục bộ của bạn.", "ManualBackupHelp": "Tùy chọn <strong>Sao lưu dữ liệu</strong> được sử dụng để sao lưu dữ liệu hệ thống để sau đó khôi phục tới máy chủ cục bộ của bạn.",
"MaxCopies": "{{copiesCount}} - số lượng bản sao lưu tối đa", "MaxCopies": "{{copiesCount}} - số lượng bản sao lưu tối đa",
"Migration": "Di chuyển", "Migration": "Di chuyển",
"NewColorScheme": "Bảng màu mới",
"PasswordMinLenght": "Độ dài mật khẩu tối thiểu", "PasswordMinLenght": "Độ dài mật khẩu tối thiểu",
"Path": "Đường dẫn", "Path": "Đường dẫn",
"PleaseNote": "Xin hãy lưu ý", "PleaseNote": "Xin hãy lưu ý",
"PleaseNoteDescription": "<0>{{pleaseNote}}</0>: địa chỉ cổng thông tin cũ của bạn sẽ khả dụng cho người dùng mới ngay khi bạn bấm vào nút <2>{{save}}</2>.", "PleaseNoteDescription": "<0>{{pleaseNote}}</0>: địa chỉ cổng thông tin cũ của bạn sẽ khả dụng cho người dùng mới ngay khi bạn bấm vào nút <2>{{save}}</2>.",
"Plugins": "Plugins",
"PortalAccess": "Truy cập cổng thông tin", "PortalAccess": "Truy cập cổng thông tin",
"PortalAccessSubTitle": "Phần này cho phép bạn cung cấp cho người dùng những cách an toàn và thuận tiện để truy cập cổng thông tin.", "PortalAccessSubTitle": "Phần này cho phép bạn cung cấp cho người dùng những cách an toàn và thuận tiện để truy cập cổng thông tin.",
"PortalDeactivation": "Vô hiệu hóa DocSpace",
"PortalDeactivationDescription": "Sử dụng tùy chọn này để tạm thời vô hiệu hóa không gian của bạn.",
"PortalDeactivationHelper": "Nếu bạn muốn vô hiệu hóa DocSpace này, không gian của bạn và tất cả thông tin được liên kết với nó sẽ bị chặn để không ai có quyền truy cập vào nó trong một khoảng thời gian cụ thể. Để làm điều đó, hãy nhấp vào nút Vô hiệu hóa. Một liên kết xác nhận hành động sẽ được gửi đến địa chỉ email của chủ sở hữu không gian.\nTrong trường hợp bạn muốn quay lại không gian và tiếp tục sử dụng nó, bạn sẽ cần sử dụng liên kết thứ hai được cung cấp trong email xác nhận. Vì vậy, xin vui lòng giữ email này ở một nơi an toàn.",
"PortalDeletion": "Xóa DocSpace",
"PortalDeletionDescription": "Sử dụng tùy chọn này để xóa vĩnh viễn không gian của bạn.",
"PortalDeletionEmailSended": "Một liên kết để xác nhận hoạt động đã được gửi đến {{ownerEmail}} (địa chỉ email của chủ sở hữu không gian).",
"PortalDeletionHelper": "Nếu bạn không nghĩ rằng bạn sẽ sử dụng không gian này và muốn xóa vĩnh viễn không gian của mình, hãy gửi yêu cầu của bạn bằng cách dùng nút Xóa. Xin lưu ý rằng bạn sẽ không thể kích hoạt lại không gian của mình hoặc khôi phục bất kỳ thông tin nào liên quan đến nó.",
"PortalIntegration": "Tích hợp không gian",
"PortalNameEmpty": "Tên tài khoản trống", "PortalNameEmpty": "Tên tài khoản trống",
"PortalNameIncorrect": "Tên tài khoản không chính xác", "PortalNameIncorrect": "Tên tài khoản không chính xác",
"PortalNameLength": "Tên tài khoản phải dài từ {{minLength}} đến {{maxLength}} ký tự", "PortalNameLength": "Tên tài khoản phải dài từ {{minLength}} đến {{maxLength}} ký tự",
@ -83,15 +148,26 @@
"RestoreBackupResetInfoWarningText": "Tất cả mật khẩu hiện tại sẽ được đặt lại. Người dùng cổng thông tin sẽ nhận được email có liên kết khôi phục quyền truy cập.", "RestoreBackupResetInfoWarningText": "Tất cả mật khẩu hiện tại sẽ được đặt lại. Người dùng cổng thông tin sẽ nhận được email có liên kết khôi phục quyền truy cập.",
"RestoreBackupWarningText": "Cổng sẽ trở nên không khả dụng trong quá trình khôi phục. Sau khi hoàn tất khôi phục tất cả các thay đổi được thực hiện sau ngày khôi phục đã chọn sẽ bị mất.", "RestoreBackupWarningText": "Cổng sẽ trở nên không khả dụng trong quá trình khôi phục. Sau khi hoàn tất khôi phục tất cả các thay đổi được thực hiện sau ngày khôi phục đã chọn sẽ bị mất.",
"RestoreDefaultButton": "Khôi phục về mặc định", "RestoreDefaultButton": "Khôi phục về mặc định",
"RoomsModule": "Phòng dự phòng",
"RoomsModuleDescription": "Bạn có thể tạo một phòng mới chuyên dùng để sao lưu, chọn một trong các phòng hiện có hoặc lưu bản sao trong phòng {{roomName}} của họ.",
"SelectFileInGZFormat": "Chọn tập tin có định dạng GZ", "SelectFileInGZFormat": "Chọn tập tin có định dạng GZ",
"SendNotificationAboutRestoring": "Gửi thông báo về khôi phục cổng cho người dùng", "SendNotificationAboutRestoring": "Gửi thông báo về khôi phục cổng cho người dùng",
"ServerSideEncryptionMethod": "Phương pháp mã hóa phía máy chủ", "ServerSideEncryptionMethod": "Phương pháp mã hóa phía máy chủ",
"ServiceUrl": "Url dịch vụ", "ServiceUrl": "Url dịch vụ",
"SessionLifetime": "Thời gian tồn tại của phiên",
"SessionLifetimeDescription": "Thời gian tồn tại của phiên cho phép đặt thời gian (tính bằng phút) trước khi người dùng không gian cần nhập lại thông tin đăng nhập để truy cập không gian.",
"SessionLifetimeHelper": "Sau khi lưu, tất cả người dùng sẽ được đăng xuất khỏi không gian.",
"SettingPasswordStrength": "Cài đặt độ mạnh của mật khẩu", "SettingPasswordStrength": "Cài đặt độ mạnh của mật khẩu",
"SettingPasswordStrengthDescription": "Cài đặt độ mạnh của mật khẩu là một cách để xác định hiệu quả của mật khẩu trong việc chống lại các cuộc tấn công phỏng đoán và tấn công brute-force.", "SettingPasswordStrengthDescription": "Cài đặt độ mạnh của mật khẩu là một cách để xác định hiệu quả của mật khẩu trong việc chống lại các cuộc tấn công phỏng đoán và tấn công brute-force.",
"SettingPasswordStrengthHelper": "Sử dụng thanh Độ dài Mật khẩu Tối thiểu để xác định độ dài của mật khẩu. Đánh dấu vào các ô thích hợp bên dưới để xác định các ký tự phải được sử dụng trong mật khẩu.", "SettingPasswordStrengthHelper": "Sử dụng thanh Độ dài Mật khẩu Tối thiểu để xác định độ dài của mật khẩu. Đánh dấu vào các ô thích hợp bên dưới để xác định các ký tự phải được sử dụng trong mật khẩu.",
"ShowFeedbackAndSupport": "Hiển thị liên kết Phản hồi & Hỗ trợ",
"ShowHelpCenter": "Hiển thị liên kết đến Trung tâm Trợ giúp",
"ShowVideoGuides": "Hiển thị liên kết đến Video Hướng dẫn",
"SingleSignOn": "Đăng nhập một lần (SSO)",
"StoragePeriod": "Thời gian lưu trữ",
"StudioTimeLanguageSettings": "Cài đặt ngôn ngữ và múi giờ", "StudioTimeLanguageSettings": "Cài đặt ngôn ngữ và múi giờ",
"SuccessfullySaveGreetingSettingsMessage": "Cài đặt Trang Chào mừng đã được lưu thành công", "SuccessfullySaveGreetingSettingsMessage": "Cài đặt Trang Chào mừng đã được lưu thành công",
"SuccessfullySavePortalNameMessage": "Không gian đã được đổi tên thành công",
"SuccessfullySaveSettingsMessage": "Cài đặt đã được cập nhật thành công", "SuccessfullySaveSettingsMessage": "Cài đặt đã được cập nhật thành công",
"TemporaryStorage": "Lưu trữ tạm thời", "TemporaryStorage": "Lưu trữ tạm thời",
"TemporaryStorageDescription": "Bản sao lưu được lưu trữ trong phần 'Sao lưu', bạn sẽ có thể tải xuống trong vòng 24 giờ sau khi tạo.", "TemporaryStorageDescription": "Bản sao lưu được lưu trữ trong phần 'Sao lưu', bạn sẽ có thể tải xuống trong vòng 24 giờ sau khi tạo.",
@ -118,5 +194,9 @@
"UseUpperCase": "Sử dụng chữ viết hoa", "UseUpperCase": "Sử dụng chữ viết hoa",
"UserAgreement": "Tôi xác nhận và muốn tiếp tục", "UserAgreement": "Tôi xác nhận và muốn tiếp tục",
"WhiteLabel": "Nhãn trắng", "WhiteLabel": "Nhãn trắng",
"YouHaveUnsavedChanges": "Bạn có các thay đổi chưa được lưu" "WhiteLabelHelper": "Sử dụng hình ảnh với nền trong suốt. (PNG, SVG, JPG)",
"WhiteLabelSubtitle": "Nhập tên công ty của bạn, tải logo lên và tùy chỉnh phong cách để phù hợp với thương hiệu của bạn.",
"WhiteLabelTooltip": "Các kích thước được hiển thị cho màn hình Retina. Đối với màn hình có độ phân giải tiêu chuẩn, chiều rộng và chiều cao logo sẽ được thay đổi kích thước tương ứng khi tải lên.",
"YouHaveUnsavedChanges": "Bạn có các thay đổi chưa được lưu",
"YourCurrentDomain": "Tên miền hiện tại của bạn"
} }

View File

@ -1 +1,61 @@
{} {
"AddCertificate": "Thêm chứng chỉ",
"AdvancedSettings": "Cài đặt Nâng cao",
"AdvancedSettingsTooltip": "Ẩn trang xác thực mặc định và tự động chuyển hướng đến dịch vụ SSO.",
"AttributeMatching": "Ánh xạ thuộc tính",
"AttributeMatchingTooltip": "Sự tương ứng của các thuộc tính Đăng nhập một lần với các mục nhập của phần 'Tài khoản.",
"Binding": "Kết hợp:",
"CertificateExist": "Chứng chỉ với cùng loại hành động đã tồn tại",
"ConfirmationText": "Tất cả dữ liệu bạn đã nhập sẽ bị mất. Bạn có chắc chắn muốn tiếp tục không?",
"CustomEntryButton": "Chú thích nút đăng nhập tùy chỉnh",
"CustomEntryTooltip": "Chú thích cho nút được sử dụng để đăng nhập vào không gian với dịch vụ Đăng nhập một lần",
"DownloadMetadataXML": "Tải siêu dữ liệu SP metadata XML",
"Encryption": "Mã hóa",
"GenerateCertificate": "Tạo chứng chỉ tự ký mới",
"Hide": "Ẩn",
"HideAdditionalParameters": "Ẩn cài đặt nâng cao",
"HideAuthPage": "Ẩn trang xác thực",
"LogoutEndpointUrl": "URL điểm cuối đăng xuất một lần IdP",
"LogoutEndpointUrlTooltip": "URL được sử dụng cho đăng xuất một lần ở phía Nhà cung cấp dịch vụ",
"NameIDFormat": "Định dạng NameId",
"NewCertificate": "Chứng chỉ mới",
"OpenCertificate": "Giấy chứng nhận công cộng",
"PlaceholderCert": "Dán hoặc nhập văn bản",
"PrivateKey": "Mã bí mật",
"ProviderURL": "Id thực thể IdP",
"ProviderURLTooltip": "Id nhà cung cấp thực thể (IdP) (URL nhà phát hành)",
"SPAssertionConsumerURL": "Assertion Consumer (hỗ trợ ĐĂNG TẢI và chuyển hướng ràng buộc)",
"SPAssertionConsumerURLTooltip": "Địa chỉ URL của nhà cung cấp dịch vụ nơi nó nhận và xử lý các xác nhận từ nhà cung cấp danh tính",
"SPEntityId": "SP Entity Id (liên kết đến siêu dữ liệu XML)",
"SPEntityIdTooltip": "Địa chỉ URL XML của nhà cung cấp dịch vụ có thể được tải xuống và sử dụng bởi nhà cung cấp danh tính để xác định rõ ràng SP",
"SPSingleLogoutURL": "URL đăng xuất SP một lần (hỗ trợ ĐĂNG TẢI và chuyển hướng ràng buộc):",
"SPSingleLogoutURLTooltip": "URL được sử dụng cho đăng xuất một lần ở phía nhà cung cấp danh tính",
"ServiceProviderSettings": "Cài đặt ONLYOFFICE SP",
"Show": "Hiển thị",
"ShowAdditionalParameters": "Hiển thị cài đặt nâng cao",
"SignOnEndpointUrl": "URL điểm cuối đăng nhập một lần IdP",
"SignOnEndpointUrlTooltip": "URL được sử dụng cho đăng nhập một lần ở phía nhà cung cấp danh tính",
"Signing": "Đang ký tên",
"SigningAndEncryption": "Ký và mã hóa",
"SpMetadata": "Siêu dữ liệu ONLYOFFICE SP",
"SsoIntro": "Phần Đăng nhập một lần cho phép bạn bật/tắt xác thực của bên thứ ba bằng SAML, do đó cung cấp cách truy cập không gian cho người dùng nhanh hơn, dễ dàng hơn và an toàn hơn.",
"StandardDecryptionAlgorithm": "Thuật toán giải mã mặc định",
"TurnOnSSO": "Thuật toán giải mã mặc định",
"TurnOnSSOCaption": "Bật tùy chọn này nếu bạn muốn tự động thêm người dùng từ dịch vụ SSO vào không gian của mình.",
"UploadXML": "Tải siêu dữ liệu từ XML để tự động điền vào các trường bắt buộc.",
"UploadXMLPlaceholder": "URL tới Siêu dữ liệu XML IdP",
"UsedFor": "Sử dụng cho",
"idpAuthRequest": "Xác minh dấu hiệu phản hồi xác thực",
"idpCertificates": "Chứng chỉ công khai IdP",
"idpCertificatesTooltip": "Chứng chỉ công khai của nhà cung cấp danh tính được sử dụng để xác minh hoặc giải mã (hoặc cả hai) các yêu cầu và phản hồi từ IdP.",
"idpSignExitRequest": "Xác minh yêu cầu đăng xuất",
"idpSignResponseRequest": "Xác minh dấu hiệu phản hồi đăng xuất",
"idpSigningAlgorithm": "Thuật toán Xác minh Ký tên Mặc định",
"spAuthRequest": "Yêu cầu xác thực ký tên",
"spCertificates": "Chứng nhận SP",
"spCertificatesTooltip": "Chứng chỉ nhà cung cấp dịch vụ được sử dụng để ký và mã hóa các yêu cầu và phản hồi từ SP",
"spDecryptStatements": "Giải mã xác nhận",
"spSignExitRequest": "Yêu cầu Đăng xuất Ký tên",
"spSignResponseRequest": "Phản hồi Đăng xuất Ký tên",
"spSigningAlgorithm": "Thuật toán ký tên"
}

View File

@ -1,4 +1,6 @@
{ {
"AppName": "Tài liệu ONLYOFFICE", "AppName": "Tài liệu ONLYOFFICE",
"AppStore": "Xin hãy đánh giá chúng tôi trên App Store",
"GooglePlay": "Trong Google Play",
"Price": "Miễn phí" "Price": "Miễn phí"
} }

View File

@ -1,5 +1,6 @@
{ {
"ArchivingData": "Lưu trữ dữ liệu", "ArchivingData": "Lưu trữ dữ liệu",
"ChooseFromList": "Chọn từ danh sách",
"ConnectingAccount": "Đang kết nối tài khoản", "ConnectingAccount": "Đang kết nối tài khoản",
"Copy": "Sao chép", "Copy": "Sao chép",
"CopyHere": "Sao chép ở đây", "CopyHere": "Sao chép ở đây",
@ -25,7 +26,9 @@
"FolderTitleYandex": "Thư mục Yandex", "FolderTitleYandex": "Thư mục Yandex",
"FolderTitlekDrive": "Thư mục kDrive", "FolderTitlekDrive": "Thư mục kDrive",
"Folders": "Thư mục", "Folders": "Thư mục",
"FormTemplates": "Mẫu biểu mẫu",
"LinkCopySuccess": "Liên kết đã được sao chép vào bộ nhớ tạm", "LinkCopySuccess": "Liên kết đã được sao chép vào bộ nhớ tạm",
"LinkValidTime": "Liên kết này chỉ có giá trị trong {{days_count}} ngày.",
"MobileAndroid": "Nhận ONLYOFFICE Documents trên Google Play", "MobileAndroid": "Nhận ONLYOFFICE Documents trên Google Play",
"MobileIos": "Tải xuống ONLYOFFICE Documents trên App Store", "MobileIos": "Tải xuống ONLYOFFICE Documents trên App Store",
"MobileLinux": "Tải xuống Trình chỉnh sửa ONLYOFFICE cho máy tính Linux", "MobileLinux": "Tải xuống Trình chỉnh sửa ONLYOFFICE cho máy tính Linux",
@ -37,10 +40,27 @@
"Other": "Khác", "Other": "Khác",
"OwnerChange": "Thay đổi chủ sở hữu", "OwnerChange": "Thay đổi chủ sở hữu",
"Presentations": "Bản trình bày", "Presentations": "Bản trình bày",
"Remove": "Xóa",
"RoleCommentator": "Người nhận xét",
"RoleCommentatorDescription": "Hoạt động với các tập tin hiện có: xem, nhận xét.",
"RoleDocSpaceAdminDescription": "Quản trị viên DocSpace có thể truy cập cài đặt DocSpace, quản lý và sao lưu phòng, mời người dùng mới và chỉ định vai trò dưới cấp độ của họ. Tất cả quản trị viên đều có quyền truy cập vào phần Cá nhân.",
"RoleEditor": "Biên tập viên",
"RoleEditorDescription": "Hoạt động với các tập tin hiện có: xem, chỉnh sửa, điền biểu mẫu, xem lại, nhận xét.",
"RoleFormFiller": "Bộ lọc biểu mẫu",
"RoleFormFillerDescription": "Hoạt động với các tập tin hiện có: xem, điền biểu mẫu, xem lại, nhận xét.",
"RolePowerUserDescription": "Người dùng cấp cao có thể tạo và chỉnh sửa các tập tin trong phòng, nhưng không thể tạo phòng, quản lý người dùng hoặc truy cập cài đặt.",
"RoleReviewer": "Người phê duyệt",
"RoleReviewerDescription": "Hoạt động với các tập tin hiện có: xem, xem lại, nhận xét.",
"RoleRoomAdminDescription": "Quản trị viên phòng có thể tạo và quản lý các phòng được chỉ định, mời người dùng mới và chỉ định vai trò dưới cấp của họ. Tất cả quản trị viên đều có quyền truy cập vào phần Cá nhân.",
"RoleUserDescription": "Người dùng chỉ có thể truy cập vào các phòng mà họ được quản trị viên mời. Họ không thể tạo phòng, thư mục hoặc tập tin riêng.",
"RoleViewer": "Người xem",
"RoleViewerDescription": "Xem tập tin",
"SearchByOwner": "Tìm kiếm theo Chủ sở hữu",
"Spreadsheets": "Bảng tính", "Spreadsheets": "Bảng tính",
"SubNewForm": "Trống", "SubNewForm": "Trống",
"SubNewFormFile": "Từ một tệp văn bản", "SubNewFormFile": "Từ một tệp văn bản",
"ThirdPartyInfo": "Thay đổi thông tin của bên thứ ba", "ThirdPartyInfo": "Thay đổi thông tin của bên thứ ba",
"ThirdPartyTitle": "Dịch vụ của bên thứ ba",
"TitleShowActions": "Hiển thị Hoạt động của File", "TitleShowActions": "Hiển thị Hoạt động của File",
"TitleShowFolderActions": "Hiển thị Hoạt động Thư mục", "TitleShowFolderActions": "Hiển thị Hoạt động Thư mục",
"TypeTitleBoxNet": "Box", "TypeTitleBoxNet": "Box",

View File

@ -1,4 +1,5 @@
{ {
"CancelUpload": "Quá trình tải lên đã bị gián đoạn. Một số tập tin chưa được tải lên.",
"EnterPassword": "Nhập mật khẩu", "EnterPassword": "Nhập mật khẩu",
"HideInput": "Ẩn", "HideInput": "Ẩn",
"Ready": "Xong", "Ready": "Xong",

View File

@ -190,8 +190,6 @@ const StyledProperties = styled.div`
} }
.property-content { .property-content {
white-space: pre-wrap;
display: -webkit-box;
overflow: hidden; overflow: hidden;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;

View File

@ -337,6 +337,7 @@ class PureHome extends React.Component {
secondaryProgressDataStoreIcon, secondaryProgressDataStoreIcon,
itemsSelectionLength, itemsSelectionLength,
itemsSelectionTitle, itemsSelectionTitle,
setItemsSelectionTitle,
refreshFiles, refreshFiles,
} = this.props; } = this.props;
@ -344,6 +345,12 @@ class PureHome extends React.Component {
this.props.setHeaderVisible(this.props.isHeaderVisible); this.props.setHeaderVisible(this.props.isHeaderVisible);
} }
if (isProgressFinished !== prevProps.isProgressFinished) {
setTimeout(() => {
refreshFiles();
}, 100);
}
if ( if (
isProgressFinished && isProgressFinished &&
itemsSelectionTitle && itemsSelectionTitle &&
@ -354,6 +361,7 @@ class PureHome extends React.Component {
itemsSelectionLength, itemsSelectionLength,
itemsSelectionTitle itemsSelectionTitle
); );
setItemsSelectionTitle(null);
} }
} }
@ -662,6 +670,7 @@ export default inject(
isSecondaryProgressFinished: isProgressFinished, isSecondaryProgressFinished: isProgressFinished,
itemsSelectionLength, itemsSelectionLength,
itemsSelectionTitle, itemsSelectionTitle,
setItemsSelectionTitle,
} = secondaryProgressDataStore; } = secondaryProgressDataStore;
const { const {
@ -726,6 +735,7 @@ export default inject(
selectionTitle, selectionTitle,
itemsSelectionLength, itemsSelectionLength,
setItemsSelectionTitle,
itemsSelectionTitle, itemsSelectionTitle,
isErrorRoomNotAvailable, isErrorRoomNotAvailable,
isRoomsFolder, isRoomsFolder,

View File

@ -33,6 +33,7 @@ const HeaderContainer = styled.div`
align-items: baseline; align-items: baseline;
.settings-section_badge { .settings-section_badge {
margin-left: 8px; margin-left: 8px;
cursor: auto;
} }
.header { .header {

View File

@ -8,6 +8,10 @@ const WhiteLabelWrapper = styled.div`
color: ${(props) => props.theme.client.settings.common.descriptionColor}; color: ${(props) => props.theme.client.settings.common.descriptionColor};
} }
.paid-badge {
cursor: auto;
}
.header-container { .header-container {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -204,6 +204,7 @@ const WhiteLabel = (props) => {
</Text> </Text>
{!isSettingPaid && ( {!isSettingPaid && (
<Badge <Badge
className="paid-badge"
backgroundColor="#EDC409" backgroundColor="#EDC409"
label={t("Common:Paid")} label={t("Common:Paid")}
isPaidBadge={true} isPaidBadge={true}

View File

@ -37,6 +37,10 @@ const StyledSettingsComponent = styled.div`
margin-right: 4px; margin-right: 4px;
} }
.paid-badge {
cursor: auto;
}
.dns-textarea { .dns-textarea {
textarea { textarea {
color: ${(props) => props.theme.text.disableColor}; color: ${(props) => props.theme.text.disableColor};

View File

@ -140,6 +140,7 @@ const DNSSettings = (props) => {
/> />
{!isSettingPaid && ( {!isSettingPaid && (
<Badge <Badge
className="paid-badge"
backgroundColor="#EDC409" backgroundColor="#EDC409"
label={t("Common:Paid")} label={t("Common:Paid")}
isPaidBadge={true} isPaidBadge={true}

View File

@ -188,6 +188,7 @@ const StyledAutoBackup = styled.div`
.auto-backup_badge { .auto-backup_badge {
height: 16px; height: 16px;
margin-left: 8px; margin-left: 8px;
cursor: auto;
} }
${(props) => !props.isEnableAuto && UnavailableStyles} ${(props) => !props.isEnableAuto && UnavailableStyles}
`; `;

View File

@ -26,6 +26,7 @@ const StyledSsoPage = styled.div`
display: flex; display: flex;
.toggle-caption_title_badge { .toggle-caption_title_badge {
margin-left: 4px; margin-left: 4px;
cursor: auto;
} }
} }
} }

View File

@ -21,6 +21,10 @@ const RootContainer = styled(Box)`
color: ${(props) => props.theme.client.settings.common.descriptionColor}; color: ${(props) => props.theme.client.settings.common.descriptionColor};
} }
.paid-badge {
cursor: auto;
}
@media ${mobile} { @media ${mobile} {
width: calc(100% - 8px); width: calc(100% - 8px);
} }

View File

@ -27,6 +27,10 @@ const MainContainer = styled.div`
max-width: 700px; max-width: 700px;
} }
.paid-badge {
cursor: auto;
}
.login-history-description { .login-history-description {
color: ${(props) => props.theme.client.settings.common.descriptionColor}; color: ${(props) => props.theme.client.settings.common.descriptionColor};
} }
@ -256,6 +260,7 @@ const HistoryMainContent = (props) => {
<MainContainer isSettingNotPaid={isSettingNotPaid}> <MainContainer isSettingNotPaid={isSettingNotPaid}>
{isSettingNotPaid && ( {isSettingNotPaid && (
<Badge <Badge
className="paid-badge"
backgroundColor="#EDC409" backgroundColor="#EDC409"
label={t("Common:Paid")} label={t("Common:Paid")}
isPaidBadge={true} isPaidBadge={true}

View File

@ -201,7 +201,7 @@ const StyledVersionRow = styled(Row)`
margin-top: 5px; margin-top: 5px;
} }
display: ${(props) => (props.showEditPanel ? "none" : "-webkit-box")}; display: ${(props) => props.showEditPanel && "none"};
overflow: hidden; overflow: hidden;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;

View File

@ -184,7 +184,9 @@ const VersionRow = (props) => {
</> </>
)} )}
<Text className="version_text">{info.comment}</Text> <Text className="version_text" truncate={true}>
{info.comment}
</Text>
</> </>
</Box> </Box>
{showEditPanel && ( {showEditPanel && (

View File

@ -368,6 +368,7 @@ class SettingsStore {
// portal not found // portal not found
const url = new URL(wrongPortalNameUrl); const url = new URL(wrongPortalNameUrl);
url.searchParams.append("url", window.location.hostname); url.searchParams.append("url", window.location.hostname);
url.searchParams.append("ref", window.location.href);
return window.location.replace(url); return window.location.replace(url);
} }
}); });

View File

@ -109,9 +109,22 @@ const StyledSocialButton = styled(ButtonWrapper).attrs((props) => ({
props.theme.socialButton.disableBackgroundColor}; props.theme.socialButton.disableBackgroundColor};
color: ${(props) => props.theme.socialButton.disableColor}; color: ${(props) => props.theme.socialButton.disableColor};
svg path { ${
fill: ${(props) => props.theme.socialButton.disableColor}; props.theme.isBase &&
css`
svg path {
opacity: 60%;
}
`
} }
${
!props.theme.isBase &&
css`
svg path {
fill: ${props.theme.socialButton.disabledSvgColor};
}
`
}}
`}; `};
.iconWrapper { .iconWrapper {
@ -149,6 +162,7 @@ const StyledSocialButton = styled(ButtonWrapper).attrs((props) => ({
path { path {
fill: ${(props) => props.isConnect && props.theme.socialButton.svg.fill}; fill: ${(props) => props.isConnect && props.theme.socialButton.svg.fill};
fill: ${(props) => !props.theme.isBase && !props.isConnect && "#FFFFFF"};
} }
} }
`; `;

View File

@ -293,7 +293,7 @@ const Base = {
width: "100%", width: "100%",
background: white, background: white,
disableBackgroundColor: "rgba(0, 0, 0, 0.08)", disableBackgroundColor: "#F8F9F9",
connectBackground: "#3B72A7", connectBackground: "#3B72A7",
hoverBackground: white, hoverBackground: white,
hoverConnectBackground: "#265A8F", hoverConnectBackground: "#265A8F",
@ -305,7 +305,8 @@ const Base = {
hoverBoxShadow: "none", hoverBoxShadow: "none",
color: "rgba(0, 0, 0, 0.54)", color: "rgba(0, 0, 0, 0.54)",
disableColor: "rgba(0, 0, 0, 0.4)", disableColor: "#333333",
disabledSvgColor: "none",
border: "none", border: "none",
text: { text: {
width: "100%", width: "100%",

View File

@ -303,6 +303,7 @@ const Dark = {
color: "rgba(0, 0, 0, 0.54)", color: "rgba(0, 0, 0, 0.54)",
disableColor: "rgba(0, 0, 0, 0.4)", disableColor: "rgba(0, 0, 0, 0.4)",
disabledSvgColor: "#474747",
border: "1px solid #474747", border: "1px solid #474747",
text: { text: {

View File

@ -5,5 +5,6 @@
"ImageFileType": "hình ảnh", "ImageFileType": "hình ảnh",
"MailMergeFileType": "Chọn tệp tin trong định dạng XLSX", "MailMergeFileType": "Chọn tệp tin trong định dạng XLSX",
"OpenSavedDocument": "Mở tài liệu đã lưu trong tab mới", "OpenSavedDocument": "Mở tài liệu đã lưu trong tab mới",
"SelectFilesType": "Chọn tệp tin loại: {{fileType}}" "SelectFilesType": "Chọn tệp tin loại: {{fileType}}",
"UsersWithoutAccess": "Một số người dùng mà bạn muốn đề cập đến không có quyền truy cập vào phòng: {{users}}"
} }

View File

@ -3,6 +3,7 @@
"CodeSubtitle": "Chúng tôi đã gửi một mã 6 chữ số đến{{email}}. Thời gian hiệu lực của mã là có hạn, hãy nhập mã càng sớm càng tốt.", "CodeSubtitle": "Chúng tôi đã gửi một mã 6 chữ số đến{{email}}. Thời gian hiệu lực của mã là có hạn, hãy nhập mã càng sớm càng tốt.",
"CodeTitle": "Mã đã được gửi qua email cho bạn", "CodeTitle": "Mã đã được gửi qua email cho bạn",
"CookieSettingsTitle": "Thời lượng của phiên", "CookieSettingsTitle": "Thời lượng của phiên",
"ErrorInvalidHeader": "Liên kết đã hết hạn",
"ErrorInvalidText": "Trong 10 giây, bạn sẽ được chuyển hướng đến <1>DocSpace</1>", "ErrorInvalidText": "Trong 10 giây, bạn sẽ được chuyển hướng đến <1>DocSpace</1>",
"ExpiredCode": "Mã này không còn hợp lệ. Yêu cầu mã mới và thử lại.", "ExpiredCode": "Mã này không còn hợp lệ. Yêu cầu mã mới và thử lại.",
"ForgotPassword": "Bạn quên mật khẩu?", "ForgotPassword": "Bạn quên mật khẩu?",
@ -23,5 +24,7 @@
"RegistrationEmailWatermark": "Email", "RegistrationEmailWatermark": "Email",
"Remember": "Nhớ tôi", "Remember": "Nhớ tôi",
"RememberHelper": "Thời lượng của phiên mặc định là 20 phút. Hãy chọn tùy chọn này để đặt thành 1 năm. Để đặt giá trị của riêng bạn, hãy đi đến Cài đặt.", "RememberHelper": "Thời lượng của phiên mặc định là 20 phút. Hãy chọn tùy chọn này để đặt thành 1 năm. Để đặt giá trị của riêng bạn, hãy đi đến Cài đặt.",
"ResendCode": "Gửi lại mã" "ResendCode": "Gửi lại mã",
"SignInWithCode": "Đăng nhập bằng mã bí mật",
"SignInWithPassword": "Đăng nhập bằng mật khẩu"
} }

View File

@ -181,14 +181,22 @@ public class ProductEntryPoint : Product
{ {
UserId = e.UserId, UserId = e.UserId,
Action = (MessageAction)e.Action, Action = (MessageAction)e.Action,
Data = e.Date, Data = e.Date
FileTitle = e.Description[0]
}; };
if (e.Action != (int)MessageAction.UserFileUpdated)
{
activityInfo.FileTitle = e.Description[0];
}
else
{
activityInfo.FileTitle = e.Description[1];
}
if (e.Action == (int)MessageAction.UserCreated if (e.Action == (int)MessageAction.UserCreated
|| e.Action == (int)MessageAction.UserUpdated) || e.Action == (int)MessageAction.UserUpdated)
{ {
if (docSpaceAdmin) if (docSpaceAdmin)
{ {
result.Add(activityInfo); result.Add(activityInfo);
} }
@ -288,7 +296,7 @@ public class ProductEntryPoint : Product
public override ProductContext Context => _productContext; public override ProductContext Context => _productContext;
public override string ApiURL => string.Empty; public override string ApiURL => string.Empty;
private async Task<Dictionary<string,bool>> GetUserRoomsWithRole(Guid userId) private async Task<Dictionary<string, bool>> GetUserRoomsWithRole(Guid userId)
{ {
var result = new Dictionary<string, bool>(); var result = new Dictionary<string, bool>();
@ -300,14 +308,14 @@ public class ProductEntryPoint : Product
foreach (var record in currentUsersRecords) foreach (var record in currentUsersRecords)
{ {
if(record.Owner == userId || record.Share == FileShare.RoomAdmin) if (record.Owner == userId || record.Share == FileShare.RoomAdmin)
{ {
result.TryAdd(record.EntryId.ToString(), true); result.TryAdd(record.EntryId.ToString(), true);
} }
else if(record.Share != FileShare.Restrict) else if (record.Share != FileShare.Restrict)
{ {
result.TryAdd(record.EntryId.ToString(), false); result.TryAdd(record.EntryId.ToString(), false);
} }
} }
var virtualRoomsFolderId = await _globalFolder.GetFolderVirtualRoomsAsync<int>(_daoFactory); var virtualRoomsFolderId = await _globalFolder.GetFolderVirtualRoomsAsync<int>(_daoFactory);

View File

@ -661,8 +661,7 @@ public class FileUtility
".html", ".htm", ".mht", ".xml", ".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps",".oxps", ".pdf", ".djvu", ".fb2", ".epub", ".xps",".oxps",
".doct", ".docy", ".doct", ".docy",
".gdoc", ".gdoc"
".docxf", ".oform"
}; };
public static readonly List<string> ExtsFormTemplate = new List<string> public static readonly List<string> ExtsFormTemplate = new List<string>

View File

@ -1,4 +1,10 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 0C6.61305 0 4.32387 0.948211 2.63604 2.63604C0.948211 4.32387 0 6.61305 0 9C0 11.3869 0.948211 13.6761 2.63604 15.364C4.32387 17.0518 6.61305 18 9 18C11.3869 18 13.6761 17.0518 15.364 15.364C17.0518 13.6761 18 11.3869 18 9C18 6.61305 17.0518 4.32387 15.364 2.63604C13.6761 0.948211 11.3869 0 9 0Z" fill="#1877F2"/> <g clip-path="url(#clip0_505_4235)">
<path d="M10.1047 11.5264H12.5862L12.9758 9.21077H10.1042V7.94516C10.1042 6.98321 10.4464 6.1302 11.4259 6.1302H13V4.10941C12.7234 4.0751 12.1385 4 11.0333 4C8.72546 4 7.37245 5.11957 7.37245 7.67025V9.21077H5V11.5264H7.37245V17.8911C7.84229 17.956 8.31819 18 8.80671 18C9.2483 18 9.67928 17.9629 10.1047 17.9101V11.5264Z" fill="white"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M2.63604 2.63604C4.32387 0.948211 6.61305 0 9 0C11.3869 0 13.6761 0.948211 15.364 2.63604C17.0518 4.32387 18 6.61305 18 9C18 11.3869 17.0518 13.6761 15.364 15.364C13.6761 17.0518 11.3869 18 9 18C8.96536 18 8.93075 17.9998 8.89615 17.9994C9.30659 17.9948 9.70812 17.9592 10.1048 17.91V11.5263H12.5863L12.9759 9.21067H10.1043V7.94507C10.1043 6.98311 10.4465 6.13011 11.426 6.13011H13.0001V4.10931L12.9852 4.10746C12.7028 4.07239 12.1192 3.9999 11.0334 3.9999C8.72556 3.9999 7.37254 5.11948 7.37254 7.67016V9.21067H5.0001V11.5263H7.37254V17.8517C5.59053 17.524 3.93515 16.6631 2.63604 15.364C0.948211 13.6761 0 11.3869 0 9C0 6.61305 0.948211 4.32387 2.63604 2.63604Z" fill="#1877F2"/>
</g>
<defs>
<clipPath id="clip0_505_4235">
<rect width="18" height="18" fill="white"/>
</clipPath>
</defs>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 768 B

After

Width:  |  Height:  |  Size: 978 B

View File

@ -6,11 +6,13 @@
"Action": "Hoạt động", "Action": "Hoạt động",
"Actions": "Hành động", "Actions": "Hành động",
"Activate": "Kích hoạt", "Activate": "Kích hoạt",
"ActivateBusinessPlan": "Kích hoạt gói dịch vụ {{planName}}?",
"Active": "Đang hoạt động", "Active": "Đang hoạt động",
"AddButton": "Thêm vào", "AddButton": "Thêm vào",
"AddFilter": "Thêm bộ lọc", "AddFilter": "Thêm bộ lọc",
"AddUsers": "Thêm người dùng", "AddUsers": "Thêm người dùng",
"Address": "Địa chỉ", "Address": "Địa chỉ",
"AdvancedFilter": "Tùy chọn tìm kiếm",
"Alert": "Cảnh báo", "Alert": "Cảnh báo",
"ApplyButton": "Áp dụng", "ApplyButton": "Áp dụng",
"Archive": "Lưu trữ", "Archive": "Lưu trữ",
@ -18,11 +20,16 @@
"Audio": "Âm thanh", "Audio": "Âm thanh",
"BarMaintenanceDescription": "Chúng tôi xin lỗi vì bất kỳ vấn đề kỹ thuật ngắn hạn nào trong hoạt động của dịch vụ có thể xảy ra trên {{targetDate}} trong quá trình cập nhật {{productName}}.", "BarMaintenanceDescription": "Chúng tôi xin lỗi vì bất kỳ vấn đề kỹ thuật ngắn hạn nào trong hoạt động của dịch vụ có thể xảy ra trên {{targetDate}} trong quá trình cập nhật {{productName}}.",
"BarMaintenanceDisclaimer": "Vui lòng đảm bảo rằng tất cả các thay đổi được lưu thành công trong ngày này.", "BarMaintenanceDisclaimer": "Vui lòng đảm bảo rằng tất cả các thay đổi được lưu thành công trong ngày này.",
"BookNow": "Đặt ngay",
"BookTeamTraining": "Đặt một buổi đào tạo nhóm với các chuyên gia tốt nhất của chúng tôi",
"ByFirstNameSorting": "Theo tên", "ByFirstNameSorting": "Theo tên",
"ByLastNameSorting": "Theo họ", "ByLastNameSorting": "Theo họ",
"Bytes": "bytes",
"CancelButton": "Hủy bỏ", "CancelButton": "Hủy bỏ",
"ChangeButton": "Thay đổi", "ChangeButton": "Thay đổi",
"ChangesSavedSuccessfully": "Đã lưu thay đổi thành công", "ChangesSavedSuccessfully": "Đã lưu thay đổi thành công",
"ClearAll": "Xóa tất cả",
"ClearFilter": "Xóa bộ lọc",
"CloseButton": "Đóng", "CloseButton": "Đóng",
"Color": "Màu sắc", "Color": "Màu sắc",
"ComingSoon": "Sắp ra mắt", "ComingSoon": "Sắp ra mắt",
@ -71,10 +78,16 @@
"Date": "Ngày", "Date": "Ngày",
"Delete": "Xóa bỏ", "Delete": "Xóa bỏ",
"Disconnect": "Ngắt kết nối", "Disconnect": "Ngắt kết nối",
"DocSpaceAdmin": "Quản trị viên DocSpace",
"DocSpaceOwner": "Chủ sở hữu DocSpace",
"Documents": "Các tài liệu", "Documents": "Các tài liệu",
"DomainIpAddress": "Các tên miền dưới dạng địa chỉ IP không được hỗ trợ", "DomainIpAddress": "Các tên miền dưới dạng địa chỉ IP không được hỗ trợ",
"Done": "Đã xong", "Done": "Đã xong",
"DontAskAgain": "Không hỏi lại tên tập tin khi tạo",
"Download": "Tải xuống", "Download": "Tải xuống",
"DropzoneTitleExsts": "(JPG hoặc PNG)",
"DropzoneTitleLink": "Chọn hình ảnh mới",
"DropzoneTitleSecondary": "hoặc thả tập tin vào đây",
"Duplicate": "Nhân bản", "Duplicate": "Nhân bản",
"EditButton": "Chỉnh sửa", "EditButton": "Chỉnh sửa",
"Email": "Email", "Email": "Email",
@ -87,11 +100,17 @@
"EnterName": "Nhập tên", "EnterName": "Nhập tên",
"Error": "Lỗi", "Error": "Lỗi",
"ErrorInternalServer": "Lỗi server nội bộ. Thử lại sau.", "ErrorInternalServer": "Lỗi server nội bộ. Thử lại sau.",
"Exabyte": "EB",
"FeedbackAndSupport": "Phản hồi & Hỗ trợ", "FeedbackAndSupport": "Phản hồi & Hỗ trợ",
"FillFormButton": "Điền vào mẫu", "FillFormButton": "Điền vào mẫu",
"FirstName": "Tên", "FirstName": "Tên",
"FreeStartupPlan": "Gói dịch vụ miễn phí {{planName}}",
"FullAccess": "Toàn quyền truy cập", "FullAccess": "Toàn quyền truy cập",
"Gigabyte": "GB",
"GracePeriodActivated": "Đã kích hoạt thời gian gia hạn",
"HasFullAccess": "Người ấy có toàn quyền sử dụng phòng",
"HelpCenter": "Trung tâm Hỗ trợ", "HelpCenter": "Trung tâm Hỗ trợ",
"HideArticleMenu": "Ẩn menu",
"Hotkeys": "Phím tắt", "Hotkeys": "Phím tắt",
"Image": "Hình ảnh", "Image": "Hình ảnh",
"IncorrectDomain": "Tên miền không chính xác", "IncorrectDomain": "Tên miền không chính xác",
@ -99,8 +118,13 @@
"IncorrectLocalPart": "Tên miền cục bộ không chính xác", "IncorrectLocalPart": "Tên miền cục bộ không chính xác",
"Info": "Thông tin", "Info": "Thông tin",
"Invite": "Mời", "Invite": "Mời",
"InviteUsers": "Mời người dùng",
"IpAddress": "Địa chỉ IP",
"Kilobyte": "KB",
"Language": "Ngôn ngữ", "Language": "Ngôn ngữ",
"LastModifiedDate": "Ngày sửa đổi lần cuối",
"LastName": "Họ", "LastName": "Họ",
"LatePayment": "Chậm thanh toán",
"LearnMore": "Tìm hiểu thêm", "LearnMore": "Tìm hiểu thêm",
"Load": "Tải", "Load": "Tải",
"LoadingDescription": "Vui lòng chờ...", "LoadingDescription": "Vui lòng chờ...",
@ -114,6 +138,9 @@
"ManyEmails": "Quá nhiều email được phân tích", "ManyEmails": "Quá nhiều email được phân tích",
"MaxLengthExceeded": "Độ dài tối đa của tên người dùng hoặc phần cục bộ khác là 64 ký tự.", "MaxLengthExceeded": "Độ dài tối đa của tên người dùng hoặc phần cục bộ khác là 64 ký tự.",
"MeLabel": "Tôi", "MeLabel": "Tôi",
"MediaError": "Không thể tải URL phương tiện",
"Megabyte": "MB",
"Member": "Thành viên",
"Members": "Thành viên", "Members": "Thành viên",
"Name": "Tên", "Name": "Tên",
"NewDocument": "Tài liệu mới", "NewDocument": "Tài liệu mới",
@ -128,19 +155,26 @@
"OFORMsGallery": "Thư viện OFORMs", "OFORMsGallery": "Thư viện OFORMs",
"OKButton": "OK", "OKButton": "OK",
"Or": "hoặc", "Or": "hoặc",
"OtherLabel": "Khác",
"OtherOperations": "Hoạt động khác", "OtherOperations": "Hoạt động khác",
"Owner": "Chủ sở hữu", "Owner": "Chủ sở hữu",
"PageOfTotalPage": "{{page}} trên {{totalPage}}", "PageOfTotalPage": "{{page}} trên {{totalPage}}",
"Pages": "Trang", "Pages": "Trang",
"Paid": "Đã thanh toán",
"Password": "Mật khẩu", "Password": "Mật khẩu",
"PasswordLimitDigits": "chữ số", "PasswordLimitDigits": "chữ số",
"PasswordLimitMessage": "Mật khẩu cần phải bao gồm", "PasswordLimitMessage": "Mật khẩu cần phải bao gồm",
"PasswordLimitSpecialSymbols": "ký tự đặc biệt", "PasswordLimitSpecialSymbols": "ký tự đặc biệt",
"PasswordLimitUpperCase": "chữ in hoa", "PasswordLimitUpperCase": "chữ in hoa",
"PasswordMinimumLength": "Chiều dài tối thiểu", "PasswordMinimumLength": "Chiều dài tối thiểu",
"PayBeforeTheEndGracePeriod": "Hãy đảm bảo thực hiện thanh toán trước khi hết thời gian gia hạn.",
"PaymentsTitle": "Thanh toán", "PaymentsTitle": "Thanh toán",
"People": "Người", "People": "Người",
"PerUserMonth": "<1>{{price}} </1><1>{{currencySymbol}} </1> mỗi quản trị viên/người dùng cấp cao/tháng",
"Petabyte": "PB",
"Phone": "Điện thoại", "Phone": "Điện thoại",
"Plugin": "Plugin",
"PowerUser": "Người dùng cấp cao",
"PreparationPortalTitle": "Đang tiến hành khôi phục cổng.", "PreparationPortalTitle": "Đang tiến hành khôi phục cổng.",
"Preview": "Xem trước", "Preview": "Xem trước",
"Previous": "Trước", "Previous": "Trước",
@ -149,19 +183,25 @@
"ProviderNotConnected": "Nhà cung cấp không được kết nối với tài khoản của bạn", "ProviderNotConnected": "Nhà cung cấp không được kết nối với tài khoản của bạn",
"PunycodeDomain": "Các tên miền punycode không được hỗ trợ", "PunycodeDomain": "Các tên miền punycode không được hỗ trợ",
"PunycodeLocalPart": "Phần cục bộ Punycode không được hỗ trợ", "PunycodeLocalPart": "Phần cục bộ Punycode không được hỗ trợ",
"ReconnectStorage": "Kết nối lại bộ nhớ",
"RecoverDescribeYourProblemPlaceholder": "Mô tả vấn đề của bạn", "RecoverDescribeYourProblemPlaceholder": "Mô tả vấn đề của bạn",
"RecoverTitle": "Khôi phục truy cập", "RecoverTitle": "Khôi phục truy cập",
"RegistrationEmail": "Email đăng ký của bạn", "RegistrationEmail": "Email đăng ký của bạn",
"RepeatInvitation": "Lặp lại lời mời",
"RequiredField": "Trường bắt buộc", "RequiredField": "Trường bắt buộc",
"ResetApplication": "Đặt lại ứng dụng", "ResetApplication": "Đặt lại ứng dụng",
"Restore": "Khôi phục", "Restore": "Khôi phục",
"RestoreHere": "Khôi phục ở đây", "RestoreHere": "Khôi phục ở đây",
"Review": "Đánh giá", "Review": "Đánh giá",
"Role": "Vai trò", "Role": "Vai trò",
"Room": "Phòng",
"RoomAdmin": "Quản trị viên phòng",
"Rooms": "Phòng",
"SameEmail": "Bạn không thể sử dụng cùng một email", "SameEmail": "Bạn không thể sử dụng cùng một email",
"SaveButton": "Lưu", "SaveButton": "Lưu",
"SaveHereButton": "Lưu ở đây", "SaveHereButton": "Lưu ở đây",
"Search": "Tìm kiếm", "Search": "Tìm kiếm",
"SearchEmptyRoomsDescription": "Không có phòng phù hợp với bộ lọc này. Hãy thử bộ lọc khác hoặc xóa bộ lọc để xem tất cả các phòng.",
"SelectAction": "Chọn", "SelectAction": "Chọn",
"SelectAll": "Chọn tất cả", "SelectAll": "Chọn tất cả",
"SelectDOCXFormat": "Chọn tệp có định dạng .DOCX", "SelectDOCXFormat": "Chọn tệp có định dạng .DOCX",
@ -169,7 +209,11 @@
"SendButton": "Gửi", "SendButton": "Gửi",
"SendRequest": "Gửi yêu cầu", "SendRequest": "Gửi yêu cầu",
"Sending": "Đang gửi...", "Sending": "Đang gửi...",
"Sessions": "Phiên",
"Settings": "Cài đặt", "Settings": "Cài đặt",
"SettingsDocSpace": "Cài đặt DocSpace",
"SettingsGeneral": "Cài đặt chung",
"SettingsPersonal": "Cá nhân",
"ShowMore": "Chi tiết", "ShowMore": "Chi tiết",
"SignInWithFacebook": "Đăng nhập bằng Facebook", "SignInWithFacebook": "Đăng nhập bằng Facebook",
"SignInWithGoogle": "Đăng nhập bằng Google", "SignInWithGoogle": "Đăng nhập bằng Google",
@ -177,6 +221,7 @@
"SignInWithSso": "Đăng nhập bằng SSO", "SignInWithSso": "Đăng nhập bằng SSO",
"SignInWithTwitter": "Đăng nhập bằng Twitter", "SignInWithTwitter": "Đăng nhập bằng Twitter",
"Size": "Kích cỡ", "Size": "Kích cỡ",
"SizeImageLarge": "Kích thước hình ảnh quá lớn, xin vui lòng chọn một hình ảnh khác.",
"SomethingWentWrong": "Đã xảy ra lỗi.", "SomethingWentWrong": "Đã xảy ra lỗi.",
"SortBy": "Xếp theo", "SortBy": "Xếp theo",
"SpacesInLocalPart": "Phần cục bộ không được chứa khoảng trắng", "SpacesInLocalPart": "Phần cục bộ không được chứa khoảng trắng",
@ -185,14 +230,18 @@
"SwitchToThumbnails": "Chuyển sang chế độ xem hình thu nhỏ", "SwitchToThumbnails": "Chuyển sang chế độ xem hình thu nhỏ",
"SwitchViewToCompact": "Chuyển sang xem đơn giản", "SwitchViewToCompact": "Chuyển sang xem đơn giản",
"Tags": "Tag", "Tags": "Tag",
"Terabyte": "TB",
"ThirdPartyStorage": "Lưu trữ của bên thứ ba", "ThirdPartyStorage": "Lưu trữ của bên thứ ba",
"Title": "Tiêu đề", "Title": "Tiêu đề",
"TitleSelectFile": "Chọn", "TitleSelectFile": "Chọn",
"Today": "Hôm nay", "Today": "Hôm nay",
"Type": "Kiểu", "Type": "Kiểu",
"UnexpectedError": "Gặp lỗi bất thường. Hãy thử lại sau hoặc liên hệ với bộ phận hỗ trợ.",
"Unknown": "Không xác định", "Unknown": "Không xác định",
"UnknownError": "Lỗi không xác định", "UnknownError": "Lỗi không xác định",
"UseLikePro": "Sử dụng ONLYOFFICE như một chuyên gia",
"User": "Người sử dụng", "User": "Người sử dụng",
"UsersInvited": "Người dùng được mời",
"Version": "Phiên bản", "Version": "Phiên bản",
"Video": "Video", "Video": "Video",
"View": "Xem", "View": "Xem",

View File

@ -198,6 +198,11 @@ public class WhitelabelController : BaseSettingsController
foreach (var logoType in (WhiteLabelLogoTypeEnum[])Enum.GetValues(typeof(WhiteLabelLogoTypeEnum))) foreach (var logoType in (WhiteLabelLogoTypeEnum[])Enum.GetValues(typeof(WhiteLabelLogoTypeEnum)))
{ {
if (logoType == WhiteLabelLogoTypeEnum.Notification)
{
continue;
}
var result = new WhiteLabelItemDto var result = new WhiteLabelItemDto
{ {
Name = logoType.ToString(), Name = logoType.ToString(),

View File

@ -186,8 +186,14 @@ public class SsoHandlerService
_log.DebugUserAlreadyAuthenticated(context.User.Identity); _log.DebugUserAlreadyAuthenticated(context.User.Identity);
} }
} }
try
userInfo = await AddUser(userInfo); {
userInfo = await AddUser(userInfo);
}
catch(Exception ex)
{
_log.WarningWithException("Failed to save user", ex);
}
var authKey = _cookiesManager.AuthenticateMeAndSetCookies(userInfo.Tenant, userInfo.Id, MessageAction.LoginSuccessViaSSO); var authKey = _cookiesManager.AuthenticateMeAndSetCookies(userInfo.Tenant, userInfo.Id, MessageAction.LoginSuccessViaSSO);
@ -228,12 +234,12 @@ public class SsoHandlerService
catch (SSOException e) catch (SSOException e)
{ {
_log.ErrorWithException(e); _log.ErrorWithException(e);
await WriteErrorToResponse(context, e.MessageKey); RedirectToLogin(context, e.MessageKey);
} }
catch (Exception e) catch (Exception e)
{ {
_log.ErrorWithException(e); _log.ErrorWithException(e);
await WriteErrorToResponse(context, MessageKey.Error); RedirectToLogin(context, MessageKey.Error);
} }
finally finally
{ {
@ -241,12 +247,17 @@ public class SsoHandlerService
//context.ApplicationInstance.CompleteRequest(); //context.ApplicationInstance.CompleteRequest();
} }
} }
private void RedirectToLogin(HttpContext context, MessageKey messageKey)
{
context.Response.Redirect(_commonLinkUtility.GetDefault() + "/login/error?messageKey=" + messageKey, false);
}
//TODO
private async Task WriteErrorToResponse(HttpContext context, MessageKey messageKey) private async Task WriteErrorToResponse(HttpContext context, MessageKey messageKey)
{ {
context.Response.StatusCode = 500; context.Response.StatusCode = 500;
context.Response.ContentType = "text/plain"; context.Response.ContentType = "text/plain";
await context.Response.WriteAsync(((int)messageKey).ToString()); await context.Response.WriteAsync(((int)messageKey).ToString());
} }
private async Task<UserInfo> AddUser(UserInfo userInfo) private async Task<UserInfo> AddUser(UserInfo userInfo)
@ -289,7 +300,7 @@ public class SsoHandlerService
throw new Exception(Resource.ErrorIncorrectUserName); throw new Exception(Resource.ErrorIncorrectUserName);
} }
await _userManager.SaveUserInfo(newUserInfo); await _userManager.UpdateUserInfo(newUserInfo);
} }
/*var photoUrl = samlResponse.GetRemotePhotoUrl(); /*var photoUrl = samlResponse.GetRemotePhotoUrl();

View File

@ -213,7 +213,7 @@ public sealed class UserManagerWrapper
_studioNotifyService.UserInfoAddedAfterInvite(newUserInfo); _studioNotifyService.UserInfoAddedAfterInvite(newUserInfo);
} }
if (fromInviteLink) if (fromInviteLink && newUserInfo.ActivationStatus != EmployeeActivationStatus.Activated)
{ {
_studioNotifyService.SendEmailActivationInstructions(newUserInfo, newUserInfo.Email); _studioNotifyService.SendEmailActivationInstructions(newUserInfo, newUserInfo.Email);
} }