@@ -0,0 +1,2 @@
|
||||
*
|
||||
!bin/
|
||||
@@ -0,0 +1,5 @@
|
||||
PORT=3001
|
||||
HOST=127.0.0.1
|
||||
BROWSER=none
|
||||
INLINE_RUNTIME_CHUNK=false
|
||||
EXTEND_ESLINT=true
|
||||
@@ -0,0 +1,3 @@
|
||||
build/*
|
||||
node_modules/*
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"plugins": ["react-intl-format"],
|
||||
"extends": ["plugin:react/recommended", "plugin:jest/recommended"],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"rules": {
|
||||
"react-intl-format/missing-formatted-message": [
|
||||
"error",
|
||||
{
|
||||
"noTrailingWhitespace": false,
|
||||
"ignoreLinks": false
|
||||
}
|
||||
],
|
||||
"react-intl-format/missing-attribute": [
|
||||
"error",
|
||||
{
|
||||
"noTrailingWhitespace": false,
|
||||
"noSpreadOperator": true
|
||||
}
|
||||
],
|
||||
"react-intl-format/missing-values": [
|
||||
"error"
|
||||
],
|
||||
"react/display-name": "off"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# yarn2 with Zero-Installs: https://yarnpkg.com/features/zero-installs
|
||||
#.yarn/*
|
||||
#!.yarn/cache
|
||||
#!.yarn/patches
|
||||
#!.yarn/plugins
|
||||
#!.yarn/releases
|
||||
#!.yarn/sdks
|
||||
#!.yarn/versions
|
||||
|
||||
# yarn2 not using Zero-Installs: https://yarnpkg.com/features/zero-installs
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/releases
|
||||
!.yarn/plugins
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
.pnp.*
|
||||
+768
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
|
||||
nodeLinker: node-modules
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.1.0.cjs
|
||||
|
||||
enableScripts: false
|
||||
enableTelemetry: false
|
||||
@@ -0,0 +1,71 @@
|
||||
SHELL := bash
|
||||
NAME := idp
|
||||
|
||||
include ../../.make/recursion.mk
|
||||
|
||||
############ tooling ############
|
||||
ifneq (, $(shell which go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI
|
||||
include ../../.bingo/Variables.mk
|
||||
endif
|
||||
|
||||
############ go tooling ############
|
||||
include ../../.make/go.mk
|
||||
|
||||
############ release ############
|
||||
include ../../.make/release.mk
|
||||
|
||||
############ docs generate ############
|
||||
include ../../.make/docs.mk
|
||||
|
||||
.PHONY: docs-generate
|
||||
docs-generate: config-docs-generate
|
||||
|
||||
############ generate ############
|
||||
include ../../.make/generate.mk
|
||||
|
||||
.PHONY: ci-go-generate
|
||||
ci-go-generate: # CI runs ci-node-generate automatically before this target
|
||||
|
||||
.PHONY: ci-node-generate
|
||||
ci-node-generate: assets
|
||||
|
||||
.PHONY: assets
|
||||
assets: yarn-build \
|
||||
assets/identifier/static \
|
||||
assets/identifier/static/logo.svg \
|
||||
assets/identifier/static/favicon.ico
|
||||
|
||||
assets/identifier/static:
|
||||
mkdir -p assets/identifier/static
|
||||
|
||||
LOGO_URL = https://raw.githubusercontent.com/owncloud/assets/main/logo.svg
|
||||
|
||||
.PHONY: assets/identifier/static/logo.svg # force overwrite
|
||||
assets/identifier/static/logo.svg:
|
||||
curl --fail -o assets/identifier/static/logo.svg ${LOGO_URL}
|
||||
|
||||
FAVICON_URL = https://raw.githubusercontent.com/owncloud/assets/main/favicon.ico
|
||||
|
||||
.PHONY: assets/identifier/static/favicon.ico # force overwrite
|
||||
assets/identifier/static/favicon.ico:
|
||||
curl --fail -o assets/identifier/static/favicon.ico ${FAVICON_URL}
|
||||
|
||||
.PHONY: yarn-build
|
||||
yarn-build: node_modules
|
||||
#yarn lint #TODO: activate
|
||||
#yarn test #TODO: activate
|
||||
yarn build
|
||||
|
||||
.PHONY: node_modules
|
||||
node_modules:
|
||||
@yarn install --immutable 2>&1 >/dev/null
|
||||
|
||||
############ licenses ############
|
||||
.PHONY: ci-node-check-licenses
|
||||
ci-node-check-licenses: node_modules
|
||||
yarn licenses:check
|
||||
|
||||
.PHONY: ci-node-save-licenses
|
||||
ci-node-save-licenses: node_modules
|
||||
yarn licenses:csv
|
||||
yarn licenses:save
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
# OpenID Connect client registry.
|
||||
clients:
|
||||
- id: web
|
||||
name: ownCloud web app
|
||||
trusted: yes
|
||||
redirect_uris:
|
||||
- {{OCIS_URL}}/
|
||||
- {{OCIS_URL}}/oidc-callback.html
|
||||
- {{OCIS_URL}}/oidc-silent-redirect.html
|
||||
origins:
|
||||
- {{OCIS_URL}}
|
||||
|
||||
- id: ocis-explorer.js
|
||||
name: oCIS Graph Explorer
|
||||
trusted: yes
|
||||
redirect_uris:
|
||||
- {{OCIS_URL}}/graph-explorer/
|
||||
origins:
|
||||
- {{OCIS_URL}}
|
||||
|
||||
|
||||
- id: xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69
|
||||
secret: UBntmLjC2yYCeHwsyj73Uwo9TAaecAetRwMw0xYcvNL9yRdLSUi0hUAHfvCHFeFh
|
||||
name: ownCloud desktop app
|
||||
application_type: native
|
||||
redirect_uris:
|
||||
- http://127.0.0.1
|
||||
- http://localhost
|
||||
|
||||
- id: e4rAsNUSIUs0lF4nbv9FmCeUkTlV9GdgTLDH1b5uie7syb90SzEVrbN7HIpmWJeD
|
||||
secret: dInFYGV33xKzhbRmpqQltYNdfLdJIfJ9L5ISoKhNoT9qZftpdWSP71VrpGR9pmoD
|
||||
name: ownCloud Android app
|
||||
application_type: native
|
||||
redirect_uris:
|
||||
- oc://android.owncloud.com
|
||||
|
||||
- id: mxd5OQDk6es5LzOzRvidJNfXLUZS2oN3oUFeXPP8LpPrhx3UroJFduGEYIBOxkY1
|
||||
secret: KFeFWWEZO9TkisIQzR3fo7hfiMXlOpaqP8CFuTbSHzV1TUuGECglPxpiVKJfOXIx
|
||||
name: ownCloud iOS app
|
||||
application_type: native
|
||||
redirect_uris:
|
||||
- oc://ios.owncloud.com
|
||||
- oc.ios://ios.owncloud.com
|
||||
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/command"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config/defaults"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := command.Execute(defaults.DefaultConfig()); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM amd64/alpine:latest
|
||||
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk add ca-certificates mailcap && \
|
||||
rm -rf /var/cache/apk/* && \
|
||||
echo 'hosts: files dns' >| /etc/nsswitch.conf
|
||||
|
||||
LABEL maintainer="ownCloud GmbH <devops@owncloud.com>" \
|
||||
org.label-schema.name="oCIS LibreGraph Connect" \
|
||||
org.label-schema.vendor="ownCloud GmbH" \
|
||||
org.label-schema.schema-version="1.0"
|
||||
|
||||
EXPOSE 9130 9134
|
||||
|
||||
ENTRYPOINT ["/usr/bin/ocis-idp"]
|
||||
CMD ["server"]
|
||||
|
||||
COPY bin/ocis-idp /usr/bin/ocis-idp
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM arm32v6/alpine:latest
|
||||
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk add ca-certificates mailcap && \
|
||||
rm -rf /var/cache/apk/* && \
|
||||
echo 'hosts: files dns' >| /etc/nsswitch.conf
|
||||
|
||||
LABEL maintainer="ownCloud GmbH <devops@owncloud.com>" \
|
||||
org.label-schema.name="oCIS LibreGraph Connect" \
|
||||
org.label-schema.vendor="ownCloud GmbH" \
|
||||
org.label-schema.schema-version="1.0"
|
||||
|
||||
EXPOSE 9130 9134
|
||||
|
||||
ENTRYPOINT ["/usr/bin/ocis-idp"]
|
||||
CMD ["server"]
|
||||
|
||||
COPY bin/ocis-idp /usr/bin/ocis-idp
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM arm64v8/alpine:latest
|
||||
|
||||
RUN apk update && \
|
||||
apk upgrade && \
|
||||
apk add ca-certificates mailcap && \
|
||||
rm -rf /var/cache/apk/* && \
|
||||
echo 'hosts: files dns' >| /etc/nsswitch.conf
|
||||
|
||||
LABEL maintainer="ownCloud GmbH <devops@owncloud.com>" \
|
||||
org.label-schema.name="oCIS LibreGraph Connect" \
|
||||
org.label-schema.vendor="ownCloud GmbH" \
|
||||
org.label-schema.schema-version="1.0"
|
||||
|
||||
EXPOSE 9130 9134
|
||||
|
||||
ENTRYPOINT ["/usr/bin/ocis-idp"]
|
||||
CMD ["server"]
|
||||
|
||||
COPY bin/ocis-idp /usr/bin/ocis-idp
|
||||
@@ -0,0 +1,22 @@
|
||||
image: owncloud/ocis-idp:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}
|
||||
{{#if build.tags}}
|
||||
tags:
|
||||
{{#each build.tags}}
|
||||
- {{this}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
manifests:
|
||||
- image: owncloud/ocis-idp:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64
|
||||
platform:
|
||||
architecture: amd64
|
||||
os: linux
|
||||
- image: owncloud/ocis-idp:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64
|
||||
platform:
|
||||
architecture: arm64
|
||||
variant: v8
|
||||
os: linux
|
||||
- image: owncloud/ocis-idp:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm
|
||||
platform:
|
||||
architecture: arm
|
||||
variant: v6
|
||||
os: linux
|
||||
@@ -0,0 +1,9 @@
|
||||
package idp
|
||||
|
||||
import (
|
||||
"embed"
|
||||
)
|
||||
|
||||
//go:generate make generate
|
||||
//go:embed assets/*
|
||||
var Assets embed.FS
|
||||
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"name": "identifier",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"homepage": ".",
|
||||
"scripts": {
|
||||
"analyze": "source-map-explorer 'build/static/js/*.js'",
|
||||
"build": "node scripts/build.js && rm -f build/service-worker.js",
|
||||
"start": "node scripts/start.js",
|
||||
"test": "node scripts/test.js --env=jsdom",
|
||||
"licenses:check": "license-checker-rseidelsohn --summary --relativeLicensePath --onlyAllow 'Python-2.0;Apache*;Apache License, Version 2.0;Apache-2.0;Apache 2.0;Artistic-2.0;BSD;BSD-3-Clause;CC-BY-3.0;CC-BY-4.0;CC0-1.0;ISC;MIT;MPL-2.0;Public Domain;Unicode-TOU;Unlicense;WTFPL' --excludePackages 'identifier;kpop;po2json;unicoderegexp'",
|
||||
"licenses:csv": "license-checker-rseidelsohn --relativeLicensePath --csv --out ../third-party-licenses/node/idp/third-party-licenses.csv",
|
||||
"licenses:save": "license-checker-rseidelsohn --relativeLicensePath --out /dev/null --files ../third-party-licenses/node/idp/third-party-licenses"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"react-app"
|
||||
]
|
||||
},
|
||||
"browserslist": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not ie <= 11",
|
||||
"not op_mini all"
|
||||
],
|
||||
"jest": {
|
||||
"collectCoverageFrom": [
|
||||
"src/**/*.js"
|
||||
],
|
||||
"moduleFileExtensions": [
|
||||
"web.js",
|
||||
"js",
|
||||
"web.ts",
|
||||
"ts",
|
||||
"web.tsx",
|
||||
"tsx",
|
||||
"json",
|
||||
"web.jsx",
|
||||
"jsx",
|
||||
"node"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"^react-native$": "react-native-web",
|
||||
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
|
||||
},
|
||||
"modulePaths": [],
|
||||
"roots": [
|
||||
"<rootDir>/src"
|
||||
],
|
||||
"setupFiles": [
|
||||
"react-app-polyfill/jsdom"
|
||||
],
|
||||
"setupFilesAfterEnv": [],
|
||||
"testEnvironment": "jest-environment-jsdom-fourteen",
|
||||
"testMatch": [
|
||||
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
|
||||
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
|
||||
],
|
||||
"transform": {
|
||||
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
|
||||
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
|
||||
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
|
||||
},
|
||||
"transformIgnorePatterns": [
|
||||
"node_modules/?!(kpop)"
|
||||
],
|
||||
"watchPlugins": [
|
||||
"jest-watch-typeahead/filename",
|
||||
"jest-watch-typeahead/testname"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.15.5",
|
||||
"@material-ui/core": "^4.8.0",
|
||||
"@material-ui/icons": "^4.5.0",
|
||||
"axios": "^0.21.1",
|
||||
"classnames": "^2.3.1",
|
||||
"dotenv": "10.0.0",
|
||||
"dotenv-expand": "5.1.0",
|
||||
"file-loader": "6.2.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"kpop": "https://download.kopano.io/community/kapp:/kpop-2.2.0.tgz",
|
||||
"query-string": "^6.14.1",
|
||||
"react": "^17.0.1",
|
||||
"react-app-polyfill": "^2.0.0",
|
||||
"react-dom": "17.0.1",
|
||||
"react-intl": "^5.20.6",
|
||||
"react-loadable": "^5.3.1",
|
||||
"react-redux": "^7.2.4",
|
||||
"react-router": "^5.0.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"redux": "^4.0.5",
|
||||
"redux-logger": "^3.0.6",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"render-if": "^0.1.1",
|
||||
"semver": "7.3.4",
|
||||
"typeface-roboto": "^1.1.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "7.13.10",
|
||||
"@svgr/webpack": "5.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.17.0",
|
||||
"@typescript-eslint/parser": "^4.32.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-jest": "^26.6.3",
|
||||
"babel-loader": "8.2.2",
|
||||
"babel-plugin-named-asset-import": "^0.3.6",
|
||||
"babel-preset-react-app": "^10.0.0",
|
||||
"camelcase": "^6.2.0",
|
||||
"case-sensitive-paths-webpack-plugin": "2.4.0",
|
||||
"css-loader": "5.2.6",
|
||||
"eslint": "^7.21.0",
|
||||
"eslint-config-react-app": "^6.0.0",
|
||||
"eslint-loader": "4.0.2",
|
||||
"eslint-plugin-flowtype": "5.7.2",
|
||||
"eslint-plugin-i18n-text": "^1.0.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jest": "^24.2.1",
|
||||
"eslint-plugin-react": "7.22.0",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-react-intl-format": "^1.1.6",
|
||||
"html-webpack-plugin": "4.5.2",
|
||||
"jest": "26.6.3",
|
||||
"jest-environment-jsdom-fourteen": "1.0.1",
|
||||
"jest-resolve": "27.2.2",
|
||||
"jest-watch-typeahead": "0.6.1",
|
||||
"license-checker-rseidelsohn": "^3.1.0",
|
||||
"mini-css-extract-plugin": "1.3.9",
|
||||
"optimize-css-assets-webpack-plugin": "5.0.4",
|
||||
"pnp-webpack-plugin": "1.6.4",
|
||||
"postcss-flexbugs-fixes": "4.1.0",
|
||||
"postcss-loader": "3.0.0",
|
||||
"postcss-normalize": "9.0.0",
|
||||
"postcss-preset-env": "6.7.0",
|
||||
"postcss-safe-parser": "5.0.2",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-dev-utils": "11.0.4",
|
||||
"react-intl-cra": "^0.3.3",
|
||||
"react-intl-po": "^2.2.2",
|
||||
"resolve": "1.20.0",
|
||||
"resolve-url-loader": "^3.1.2",
|
||||
"sass-loader": "11.0.1",
|
||||
"source-map-explorer": "^2.5.2",
|
||||
"style-loader": "2.0.0",
|
||||
"terser-webpack-plugin": "4.2.3",
|
||||
"ts-pnp": "1.2.0",
|
||||
"url-loader": "4.1.1",
|
||||
"webpack": "4.46.0",
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"webpack-manifest-plugin": "3.1.0",
|
||||
"workbox-webpack-plugin": "4.3.1",
|
||||
"yarn-deduplicate": "^3.1.0"
|
||||
},
|
||||
"packageManager": "yarn@3.1.0"
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/assetsfs"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// New returns a new http filesystem to serve assets.
|
||||
func New(opts ...Option) http.FileSystem {
|
||||
options := newOptions(opts...)
|
||||
return assetsfs.New(idp.Assets, options.Config.Asset.Path, options.Logger)
|
||||
}
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Config *config.Config
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
// Config provides a function to set the config option.
|
||||
func Config(val *config.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.Config = val
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config/parser"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/logging"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Health is the entrypoint for the health command.
|
||||
func Health(cfg *config.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "health",
|
||||
Usage: "check health status",
|
||||
Category: "info",
|
||||
Before: func(c *cli.Context) error {
|
||||
return parser.ParseConfig(cfg)
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
logger := logging.Configure(cfg.Service.Name, cfg.Log)
|
||||
|
||||
resp, err := http.Get(
|
||||
fmt.Sprintf(
|
||||
"http://%s/healthz",
|
||||
cfg.Debug.Addr,
|
||||
),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Fatal().
|
||||
Err(err).
|
||||
Msg("Failed to request health check")
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
logger.Fatal().
|
||||
Int("code", resp.StatusCode).
|
||||
Msg("Health seems to be in bad state")
|
||||
}
|
||||
|
||||
logger.Debug().
|
||||
Int("code", resp.StatusCode).
|
||||
Msg("Health got a good state")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/clihelper"
|
||||
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
|
||||
"github.com/thejerf/suture/v4"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// GetCommands provides all commands for this service
|
||||
func GetCommands(cfg *config.Config) cli.Commands {
|
||||
return []*cli.Command{
|
||||
// start this service
|
||||
Server(cfg),
|
||||
|
||||
// interaction with this service
|
||||
|
||||
// infos about this service
|
||||
Health(cfg),
|
||||
Version(cfg),
|
||||
}
|
||||
}
|
||||
|
||||
// Execute is the entry point for the ocis-idp command.
|
||||
func Execute(cfg *config.Config) error {
|
||||
app := clihelper.DefaultApp(&cli.App{
|
||||
Name: "ocis-idp",
|
||||
Usage: "Serve IDP API for oCIS",
|
||||
Commands: GetCommands(cfg),
|
||||
})
|
||||
|
||||
cli.HelpFlag = &cli.BoolFlag{
|
||||
Name: "help,h",
|
||||
Usage: "Show the help",
|
||||
}
|
||||
|
||||
return app.Run(os.Args)
|
||||
}
|
||||
|
||||
// SutureService allows for the idp command to be embedded and supervised by a suture supervisor tree.
|
||||
type SutureService struct {
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
// NewSutureService creates a new idp.SutureService
|
||||
func NewSutureService(cfg *ociscfg.Config) suture.Service {
|
||||
cfg.IDP.Commons = cfg.Commons
|
||||
return SutureService{
|
||||
cfg: cfg.IDP,
|
||||
}
|
||||
}
|
||||
|
||||
func (s SutureService) Serve(ctx context.Context) error {
|
||||
s.cfg.Context = ctx
|
||||
if err := Execute(s.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/oklog/run"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config/parser"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/logging"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/metrics"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/server/debug"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/server/http"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/tracing"
|
||||
"github.com/owncloud/ocis/ocis-pkg/version"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Server is the entrypoint for the server command.
|
||||
func Server(cfg *config.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "server",
|
||||
Usage: fmt.Sprintf("start %s extension without runtime (unsupervised mode)", cfg.Service.Name),
|
||||
Category: "server",
|
||||
Before: func(c *cli.Context) error {
|
||||
return parser.ParseConfig(cfg)
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
logger := logging.Configure(cfg.Service.Name, cfg.Log)
|
||||
err := tracing.Configure(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var (
|
||||
gr = run.Group{}
|
||||
ctx, cancel = func() (context.Context, context.CancelFunc) {
|
||||
if cfg.Context == nil {
|
||||
return context.WithCancel(context.Background())
|
||||
}
|
||||
return context.WithCancel(cfg.Context)
|
||||
}()
|
||||
metrics = metrics.New()
|
||||
)
|
||||
|
||||
defer cancel()
|
||||
|
||||
metrics.BuildInfo.WithLabelValues(version.String).Set(1)
|
||||
|
||||
{
|
||||
server, err := http.Server(
|
||||
http.Logger(logger),
|
||||
http.Context(ctx),
|
||||
http.Config(cfg),
|
||||
http.Metrics(metrics),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Info().
|
||||
Err(err).
|
||||
Str("transport", "http").
|
||||
Msg("Failed to initialize server")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
gr.Add(func() error {
|
||||
return server.Run()
|
||||
}, func(_ error) {
|
||||
logger.Info().
|
||||
Str("transport", "http").
|
||||
Msg("Shutting down server")
|
||||
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
server, err := debug.Server(
|
||||
debug.Logger(logger),
|
||||
debug.Context(ctx),
|
||||
debug.Config(cfg),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Info().Err(err).Str("transport", "debug").Msg("Failed to initialize server")
|
||||
return err
|
||||
}
|
||||
|
||||
gr.Add(server.ListenAndServe, func(_ error) {
|
||||
_ = server.Shutdown(ctx)
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
return gr.Run()
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/registry"
|
||||
"github.com/owncloud/ocis/ocis-pkg/version"
|
||||
|
||||
tw "github.com/olekukonko/tablewriter"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Version prints the service versions of all running instances.
|
||||
func Version(cfg *config.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "version",
|
||||
Usage: "print the version of this binary and the running extension instances",
|
||||
Category: "info",
|
||||
Action: func(c *cli.Context) error {
|
||||
fmt.Println("Version: " + version.String)
|
||||
fmt.Printf("Compiled: %s\n", version.Compiled())
|
||||
fmt.Println("")
|
||||
|
||||
reg := registry.GetRegistry()
|
||||
services, err := reg.GetService(cfg.HTTP.Namespace + "." + cfg.Service.Name)
|
||||
if err != nil {
|
||||
fmt.Println(fmt.Errorf("could not get %s services from the registry: %v", cfg.Service.Name, err))
|
||||
return err
|
||||
}
|
||||
|
||||
if len(services) == 0 {
|
||||
fmt.Println("No running " + cfg.Service.Name + " service found.")
|
||||
return nil
|
||||
}
|
||||
|
||||
table := tw.NewWriter(os.Stdout)
|
||||
table.SetHeader([]string{"Version", "Address", "Id"})
|
||||
table.SetAutoFormatHeaders(false)
|
||||
for _, s := range services {
|
||||
for _, n := range s.Nodes {
|
||||
table.Append([]string{s.Version, n.Address, n.Id})
|
||||
}
|
||||
}
|
||||
table.Render()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/shared"
|
||||
)
|
||||
|
||||
// Config combines all available configuration parts.
|
||||
type Config struct {
|
||||
*shared.Commons `yaml:"-"`
|
||||
|
||||
Service Service `yaml:"-"`
|
||||
|
||||
Tracing *Tracing `yaml:"tracing"`
|
||||
Log *Log `yaml:"log"`
|
||||
Debug Debug `yaml:"debug"`
|
||||
|
||||
HTTP HTTP `yaml:"http"`
|
||||
|
||||
Asset Asset `yaml:"asset"`
|
||||
IDP Settings `yaml:"idp"`
|
||||
Ldap Ldap `yaml:"ldap"`
|
||||
|
||||
Context context.Context `yaml:"-"`
|
||||
}
|
||||
|
||||
// Ldap defines the available LDAP configuration.
|
||||
type Ldap struct {
|
||||
URI string `yaml:"uri" env:"LDAP_URI;IDP_LDAP_URI"`
|
||||
|
||||
BindDN string `yaml:"bind_dn" env:"LDAP_BIND_DN;IDP_LDAP_BIND_DN"`
|
||||
BindPassword string `yaml:"bind_password" env:"LDAP_BIND_PASSWORD;IDP_LDAP_BIND_PASSWORD"`
|
||||
|
||||
BaseDN string `yaml:"base_dn" env:"LDAP_USER_BASE_DN,IDP_LDAP_BASE_DN"`
|
||||
Scope string `yaml:"scope" env:"LDAP_USER_SCOPE;IDP_LDAP_SCOPE"`
|
||||
|
||||
LoginAttribute string `yaml:"login_attribute" env:"IDP_LDAP_LOGIN_ATTRIBUTE"`
|
||||
EmailAttribute string `yaml:"email_attribute" env:"LDAP_USER_SCHEMA_MAIL;IDP_LDAP_EMAIL_ATTRIBUTE"`
|
||||
NameAttribute string `yaml:"name_attribute" env:"LDAP_USER_SCHEMA_USERNAME;IDP_LDAP_NAME_ATTRIBUTE"`
|
||||
UUIDAttribute string `yaml:"uuid_attribute" env:"LDAP_USER_SCHEMA_ID;IDP_LDAP_UUID_ATTRIBUTE"`
|
||||
UUIDAttributeType string `yaml:"uuid_attribute_type" env:"IDP_LDAP_UUID_ATTRIBUTE_TYPE"`
|
||||
|
||||
Filter string `yaml:"filter" env:"LDAP_USER_FILTER;IDP_LDAP_FILTER"`
|
||||
ObjectClass string `yaml:"objectclass" env:"LDAP_USER_OBJECTCLASS;IDP_LDAP_OBJECTCLASS"`
|
||||
}
|
||||
|
||||
// Asset defines the available asset configuration.
|
||||
type Asset struct {
|
||||
Path string `yaml:"asset" env:"IDP_ASSET_PATH"`
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
// don't change the order of elements in this struct
|
||||
// it needs to match github.com/libregraph/lico/bootstrap.Settings
|
||||
|
||||
Iss string `yaml:"iss" env:"OCIS_URL;IDP_ISS"`
|
||||
|
||||
IdentityManager string `yaml:"identity_manager" env:"IDP_IDENTITY_MANAGER"`
|
||||
|
||||
URIBasePath string `yaml:"uri_base_path" env:"IDP_URI_BASE_PATH"`
|
||||
|
||||
SignInURI string `yaml:"sign_in_uri" env:"IDP_SIGN_IN_URI"`
|
||||
SignedOutURI string `yaml:"signed_out_uri" env:"IDP_SIGN_OUT_URI"`
|
||||
|
||||
AuthorizationEndpointURI string `yaml:"authorization_endpoint_uri" env:"IDP_ENDPOINT_URI"`
|
||||
EndsessionEndpointURI string `yaml:"end_session_endpoint_uri" env:"IDP_ENDSESSION_ENDPOINT_URI"`
|
||||
|
||||
Insecure bool `yaml:"insecure" env:"IDP_INSECURE"`
|
||||
|
||||
TrustedProxy []string `yaml:"trusted_proxy"` //TODO: how to configure this via env?
|
||||
|
||||
AllowScope []string `yaml:"allow_scope"` // TODO: is this even needed?
|
||||
AllowClientGuests bool `yaml:"allow_client_guests" env:"IDP_ALLOW_CLIENT_GUESTS"`
|
||||
AllowDynamicClientRegistration bool `yaml:"allow_dynamic_client_registration" env:"IDP_ALLOW_DYNAMIC_CLIENT_REGISTRATION"`
|
||||
|
||||
EncryptionSecretFile string `yaml:"encrypt_secret_file" env:"IDP_ENCRYPTION_SECRET"`
|
||||
|
||||
Listen string
|
||||
|
||||
IdentifierClientDisabled bool `yaml:"identifier_client_disabled" env:"IDP_DISABLE_IDENTIFIER_WEBAPP"`
|
||||
IdentifierClientPath string `yaml:"identifier_client_path" env:"IDP_IDENTIFIER_CLIENT_PATH"`
|
||||
IdentifierRegistrationConf string `yaml:"identifier_registration_conf" env:"IDP_IDENTIFIER_REGISTRATION_CONF"`
|
||||
IdentifierScopesConf string `yaml:"identifier_scopes_conf" env:"IDP_IDENTIFIER_SCOPES_CONF"`
|
||||
IdentifierDefaultBannerLogo string
|
||||
IdentifierDefaultSignInPageText string
|
||||
IdentifierDefaultUsernameHintText string
|
||||
IdentifierUILocales []string
|
||||
|
||||
SigningKid string `yaml:"signing_kid" env:"IDP_SIGNING_KID"`
|
||||
SigningMethod string `yaml:"signing_method" env:"IDP_SIGNING_METHOD"`
|
||||
SigningPrivateKeyFiles []string `yaml:"signing_private_key_files"` // TODO: is this even needed?
|
||||
ValidationKeysPath string `yaml:"validation_keys_path" env:"IDP_VALIDATION_KEYS_PATH"`
|
||||
|
||||
CookieBackendURI string
|
||||
CookieNames []string
|
||||
|
||||
AccessTokenDurationSeconds uint64 `yaml:"access_token_duration_seconds" env:"IDP_ACCESS_TOKEN_EXPIRATION"`
|
||||
IDTokenDurationSeconds uint64 `yaml:"id_token_duration_seconds" env:"IDP_ID_TOKEN_EXPIRATION"`
|
||||
RefreshTokenDurationSeconds uint64 `yaml:"refresh_token_duration_seconds" env:"IDP_REFRESH_TOKEN_EXPIRATION"`
|
||||
DyamicClientSecretDurationSeconds uint64 `yaml:"dynamic_client_secret_duration_seconds" env:""`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package config
|
||||
|
||||
// Debug defines the available debug configuration.
|
||||
type Debug struct {
|
||||
Addr string `yaml:"addr" env:"IDP_DEBUG_ADDR"`
|
||||
Token string `yaml:"token" env:"IDP_DEBUG_TOKEN"`
|
||||
Pprof bool `yaml:"pprof" env:"IDP_DEBUG_PPROF"`
|
||||
Zpages bool `yaml:"zpages" env:"IDP_DEBUG_ZPAGES"`
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package defaults
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/config/defaults"
|
||||
)
|
||||
|
||||
func FullDefaultConfig() *config.Config {
|
||||
cfg := DefaultConfig()
|
||||
|
||||
EnsureDefaults(cfg)
|
||||
Sanitize(cfg)
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func DefaultConfig() *config.Config {
|
||||
return &config.Config{
|
||||
Debug: config.Debug{
|
||||
Addr: "127.0.0.1:9134",
|
||||
},
|
||||
HTTP: config.HTTP{
|
||||
Addr: "127.0.0.1:9130",
|
||||
Root: "/",
|
||||
Namespace: "com.owncloud.web",
|
||||
TLSCert: path.Join(defaults.BaseDataPath(), "idp", "server.crt"),
|
||||
TLSKey: path.Join(defaults.BaseDataPath(), "idp", "server.key"),
|
||||
TLS: false,
|
||||
},
|
||||
Service: config.Service{
|
||||
Name: "idp",
|
||||
},
|
||||
Asset: config.Asset{},
|
||||
IDP: config.Settings{
|
||||
Iss: "https://localhost:9200",
|
||||
IdentityManager: "ldap",
|
||||
URIBasePath: "",
|
||||
SignInURI: "",
|
||||
SignedOutURI: "",
|
||||
AuthorizationEndpointURI: "",
|
||||
EndsessionEndpointURI: "",
|
||||
Insecure: false,
|
||||
TrustedProxy: nil,
|
||||
AllowScope: nil,
|
||||
AllowClientGuests: false,
|
||||
AllowDynamicClientRegistration: false,
|
||||
EncryptionSecretFile: "",
|
||||
Listen: "",
|
||||
IdentifierClientDisabled: true,
|
||||
IdentifierClientPath: path.Join(defaults.BaseDataPath(), "idp"),
|
||||
IdentifierRegistrationConf: path.Join(defaults.BaseDataPath(), "idp", "identifier-registration.yaml"),
|
||||
IdentifierScopesConf: "",
|
||||
IdentifierDefaultBannerLogo: "",
|
||||
IdentifierDefaultSignInPageText: "",
|
||||
IdentifierDefaultUsernameHintText: "",
|
||||
SigningKid: "",
|
||||
SigningMethod: "PS256",
|
||||
SigningPrivateKeyFiles: nil,
|
||||
ValidationKeysPath: "",
|
||||
CookieBackendURI: "",
|
||||
CookieNames: nil,
|
||||
AccessTokenDurationSeconds: 60 * 10, // 10 minutes
|
||||
IDTokenDurationSeconds: 60 * 60, // 1 hour
|
||||
RefreshTokenDurationSeconds: 60 * 60 * 24 * 365 * 3, // 1 year
|
||||
DyamicClientSecretDurationSeconds: 0,
|
||||
},
|
||||
Ldap: config.Ldap{
|
||||
URI: "ldap://localhost:9125",
|
||||
BindDN: "cn=idp,ou=sysusers,dc=ocis,dc=test",
|
||||
BindPassword: "idp",
|
||||
BaseDN: "ou=users,dc=ocis,dc=test",
|
||||
Scope: "sub",
|
||||
LoginAttribute: "cn",
|
||||
EmailAttribute: "mail",
|
||||
NameAttribute: "displayName",
|
||||
UUIDAttribute: "uid",
|
||||
UUIDAttributeType: "text",
|
||||
Filter: "",
|
||||
ObjectClass: "posixAccount",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func EnsureDefaults(cfg *config.Config) {
|
||||
// provide with defaults for shared logging, since we need a valid destination address for BindEnv.
|
||||
if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
|
||||
cfg.Log = &config.Log{
|
||||
Level: cfg.Commons.Log.Level,
|
||||
Pretty: cfg.Commons.Log.Pretty,
|
||||
Color: cfg.Commons.Log.Color,
|
||||
File: cfg.Commons.Log.File,
|
||||
}
|
||||
} else if cfg.Log == nil {
|
||||
cfg.Log = &config.Log{}
|
||||
}
|
||||
// provide with defaults for shared tracing, since we need a valid destination address for BindEnv.
|
||||
if cfg.Tracing == nil && cfg.Commons != nil && cfg.Commons.Tracing != nil {
|
||||
cfg.Tracing = &config.Tracing{
|
||||
Enabled: cfg.Commons.Tracing.Enabled,
|
||||
Type: cfg.Commons.Tracing.Type,
|
||||
Endpoint: cfg.Commons.Tracing.Endpoint,
|
||||
Collector: cfg.Commons.Tracing.Collector,
|
||||
}
|
||||
} else if cfg.Tracing == nil {
|
||||
cfg.Tracing = &config.Tracing{}
|
||||
}
|
||||
}
|
||||
|
||||
func Sanitize(cfg *config.Config) {
|
||||
// sanitize config
|
||||
if cfg.HTTP.Root != "/" {
|
||||
cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package config
|
||||
|
||||
// HTTP defines the available http configuration.
|
||||
type HTTP struct {
|
||||
Addr string `yaml:"addr" env:"IDP_HTTP_ADDR"`
|
||||
Root string `yaml:"root" env:"IDP_HTTP_ROOT"`
|
||||
Namespace string `yaml:"-"`
|
||||
TLSCert string `yaml:"tls_cert" env:"IDP_TRANSPORT_TLS_CERT"`
|
||||
TLSKey string `yaml:"tls_key" env:"IDP_TRANSPORT_TLS_KEY"`
|
||||
TLS bool `yaml:"tls" env:"IDP_TLS"`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package config
|
||||
|
||||
// Log defines the available log configuration.
|
||||
type Log struct {
|
||||
Level string `yaml:"level" env:"OCIS_LOG_LEVEL;IDP_LOG_LEVEL"`
|
||||
Pretty bool `yaml:"pretty" env:"OCIS_LOG_PRETTY;IDP_LOG_PRETTY"`
|
||||
Color bool `yaml:"color" env:"OCIS_LOG_COLOR;IDP_LOG_COLOR"`
|
||||
File string `yaml:"file" env:"OCIS_LOG_FILE;IDP_LOG_FILE"`
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config/defaults"
|
||||
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/config/envdecode"
|
||||
)
|
||||
|
||||
// ParseConfig loads accounts configuration from known paths.
|
||||
func ParseConfig(cfg *config.Config) error {
|
||||
_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defaults.EnsureDefaults(cfg)
|
||||
|
||||
// load all env variables relevant to the config in the current context.
|
||||
if err := envdecode.Decode(cfg); err != nil {
|
||||
// no environment variable set for this config is an expected "error"
|
||||
if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
defaults.Sanitize(cfg)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package config
|
||||
|
||||
// Service defines the available service configuration.
|
||||
type Service struct {
|
||||
Name string `yaml:"-"`
|
||||
PasswordResetURI string `yaml:"password_reset_uri" env:"IDP_PASSWORD_RESET_URI" desc:"The URI where a user can reset their password."`
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package config
|
||||
|
||||
// Tracing defines the available tracing configuration.
|
||||
type Tracing struct {
|
||||
Enabled bool `yaml:"enabled" env:"OCIS_TRACING_ENABLED;IDP_TRACING_ENABLED"`
|
||||
Type string `yaml:"type" env:"OCIS_TRACING_TYPE;IDP_TRACING_TYPE"`
|
||||
Endpoint string `yaml:"endpoint" env:"OCIS_TRACING_ENDPOINT;IDP_TRACING_ENDPOINT"`
|
||||
Collector string `yaml:"collector" env:"OCIS_TRACING_COLLECTOR;IDP_TRACING_COLLECTOR"`
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// LoggerFromConfig initializes a service-specific logger instance.
|
||||
func Configure(name string, cfg *config.Log) log.Logger {
|
||||
return log.NewLogger(
|
||||
log.Name(name),
|
||||
log.Level(cfg.Level),
|
||||
log.Pretty(cfg.Pretty),
|
||||
log.Color(cfg.Color),
|
||||
log.File(cfg.File),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package metrics
|
||||
|
||||
import "github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
var (
|
||||
// Namespace defines the namespace for the defines metrics.
|
||||
Namespace = "ocis"
|
||||
|
||||
// Subsystem defines the subsystem for the defines metrics.
|
||||
Subsystem = "idp"
|
||||
)
|
||||
|
||||
// Metrics defines the available metrics of this service.
|
||||
type Metrics struct {
|
||||
// Counter *prometheus.CounterVec
|
||||
BuildInfo *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
// New initializes the available metrics.
|
||||
func New() *Metrics {
|
||||
m := &Metrics{
|
||||
// Counter: prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
// Namespace: Namespace,
|
||||
// Subsystem: Subsystem,
|
||||
// Name: "greet_total",
|
||||
// Help: "How many greeting requests processed",
|
||||
// }, []string{}),
|
||||
BuildInfo: prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: Namespace,
|
||||
Subsystem: Subsystem,
|
||||
Name: "build_info",
|
||||
Help: "Build Information",
|
||||
}, []string{"version"}),
|
||||
}
|
||||
|
||||
// prometheus.Register(
|
||||
// m.Counter,
|
||||
// )
|
||||
|
||||
_ = prometheus.Register(
|
||||
m.BuildInfo,
|
||||
)
|
||||
|
||||
return m
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
idpTracing "github.com/owncloud/ocis/extensions/idp/pkg/tracing"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
)
|
||||
|
||||
// Static is a middleware that serves static assets.
|
||||
func Static(root string, fs http.FileSystem) func(http.Handler) http.Handler {
|
||||
if !strings.HasSuffix(root, "/") {
|
||||
root = root + "/"
|
||||
}
|
||||
|
||||
static := http.StripPrefix(
|
||||
root,
|
||||
http.FileServer(
|
||||
fs,
|
||||
),
|
||||
)
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, span := idpTracing.TraceProvider.Tracer("idp").Start(r.Context(), "serve static asset")
|
||||
defer span.End()
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
// serve the static assets for the identifier web app
|
||||
if strings.HasPrefix(r.URL.Path, "/signin/v1/static/") {
|
||||
if strings.HasSuffix(r.URL.Path, "/") {
|
||||
// but no listing of folders
|
||||
span.SetAttributes(attribute.KeyValue{Key: "path", Value: attribute.StringValue(r.URL.Path)})
|
||||
span.SetStatus(codes.Error, "asset not found")
|
||||
http.NotFound(w, r)
|
||||
} else {
|
||||
r.URL.Path = strings.Replace(r.URL.Path, "/signin/v1/static/", "/signin/v1/identifier/static/", 1)
|
||||
span.SetAttributes(attribute.KeyValue{Key: "server", Value: attribute.StringValue(r.URL.Path)})
|
||||
static.ServeHTTP(w, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
span.SetAttributes(attribute.KeyValue{Key: "path", Value: attribute.StringValue(r.URL.Path)})
|
||||
span.SetStatus(codes.Ok, "ok")
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Context context.Context
|
||||
Config *config.Config
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
// Context provides a function to set the context option.
|
||||
func Context(val context.Context) Option {
|
||||
return func(o *Options) {
|
||||
o.Context = val
|
||||
}
|
||||
}
|
||||
|
||||
// Config provides a function to set the config option.
|
||||
func Config(val *config.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.Config = val
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/ocis-pkg/service/debug"
|
||||
"github.com/owncloud/ocis/ocis-pkg/shared"
|
||||
"github.com/owncloud/ocis/ocis-pkg/version"
|
||||
)
|
||||
|
||||
// Server initializes the debug service and server.
|
||||
func Server(opts ...Option) (*http.Server, error) {
|
||||
options := newOptions(opts...)
|
||||
|
||||
return debug.NewService(
|
||||
debug.Logger(options.Logger),
|
||||
debug.Name(options.Config.Service.Name),
|
||||
debug.Version(version.String),
|
||||
debug.Address(options.Config.Debug.Addr),
|
||||
debug.Token(options.Config.Debug.Token),
|
||||
debug.Pprof(options.Config.Debug.Pprof),
|
||||
debug.Zpages(options.Config.Debug.Zpages),
|
||||
debug.Health(health(options.Config, options.Logger)),
|
||||
debug.Ready(ready(options.Config)),
|
||||
), nil
|
||||
}
|
||||
|
||||
// health implements the health check.
|
||||
func health(cfg *config.Config, l log.Logger) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
targetHost, err := url.Parse(cfg.Ldap.URI)
|
||||
if err != nil {
|
||||
l.Fatal().Err(err).Str("uri", cfg.Ldap.URI).Msg("invalid LDAP URI")
|
||||
}
|
||||
err = shared.RunChecklist(shared.TCPConnect(targetHost.Host))
|
||||
retVal := http.StatusOK
|
||||
if err != nil {
|
||||
l.Error().Err(err).Msg("Healtcheck failed")
|
||||
retVal = http.StatusInternalServerError
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(retVal)
|
||||
|
||||
_, err = io.WriteString(w, http.StatusText(retVal))
|
||||
if err != nil {
|
||||
l.Fatal().Err(err).Msg("Could not write health check body")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ready implements the ready check.
|
||||
func ready(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
// if we can call this function, a http(200) is a valid response as
|
||||
// there is nothing we can check at this point for IDP
|
||||
// if there is a mishap when initializing, there is a minimal (talking ms or ns window)
|
||||
// timeframe where this code is callable
|
||||
_, err := io.WriteString(w, http.StatusText(http.StatusOK))
|
||||
// io.WriteString should not fail but if it does we want to know.
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/metrics"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Namespace string
|
||||
Logger log.Logger
|
||||
Context context.Context
|
||||
Config *config.Config
|
||||
Metrics *metrics.Metrics
|
||||
Flags []cli.Flag
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
// Context provides a function to set the context option.
|
||||
func Context(val context.Context) Option {
|
||||
return func(o *Options) {
|
||||
o.Context = val
|
||||
}
|
||||
}
|
||||
|
||||
// Config provides a function to set the config option.
|
||||
func Config(val *config.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.Config = val
|
||||
}
|
||||
}
|
||||
|
||||
// Metrics provides a function to set the metrics option.
|
||||
func Metrics(val *metrics.Metrics) Option {
|
||||
return func(o *Options) {
|
||||
o.Metrics = val
|
||||
}
|
||||
}
|
||||
|
||||
// Flags provides a function to set the flags option.
|
||||
func Flags(val []cli.Flag) Option {
|
||||
return func(o *Options) {
|
||||
o.Flags = append(o.Flags, val...)
|
||||
}
|
||||
}
|
||||
|
||||
// Namespace provides a function to set the namespace option.
|
||||
func Namespace(val string) Option {
|
||||
return func(o *Options) {
|
||||
o.Namespace = val
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"os"
|
||||
|
||||
chimiddleware "github.com/go-chi/chi/v5/middleware"
|
||||
svc "github.com/owncloud/ocis/extensions/idp/pkg/service/v0"
|
||||
pkgcrypto "github.com/owncloud/ocis/ocis-pkg/crypto"
|
||||
"github.com/owncloud/ocis/ocis-pkg/middleware"
|
||||
"github.com/owncloud/ocis/ocis-pkg/service/http"
|
||||
"github.com/owncloud/ocis/ocis-pkg/version"
|
||||
"go-micro.dev/v4"
|
||||
)
|
||||
|
||||
// Server initializes the http service and server.
|
||||
func Server(opts ...Option) (http.Service, error) {
|
||||
options := newOptions(opts...)
|
||||
|
||||
var tlsConfig *tls.Config
|
||||
if options.Config.HTTP.TLS {
|
||||
_, certErr := os.Stat(options.Config.HTTP.TLSCert)
|
||||
_, keyErr := os.Stat(options.Config.HTTP.TLSKey)
|
||||
|
||||
if os.IsNotExist(certErr) || os.IsNotExist(keyErr) {
|
||||
options.Logger.Info().Msgf("Generating certs")
|
||||
if err := pkgcrypto.GenCert(options.Config.HTTP.TLSCert, options.Config.HTTP.TLSKey, options.Logger); err != nil {
|
||||
options.Logger.Fatal().Err(err).Msg("Could not setup TLS")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
cer, err := tls.LoadX509KeyPair(options.Config.HTTP.TLSCert, options.Config.HTTP.TLSKey)
|
||||
if err != nil {
|
||||
options.Logger.Fatal().Err(err).Msg("Could not setup TLS")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
tlsConfig = &tls.Config{MinVersion: tls.VersionTLS12, Certificates: []tls.Certificate{cer}}
|
||||
}
|
||||
|
||||
service := http.NewService(
|
||||
http.Logger(options.Logger),
|
||||
http.Namespace(options.Config.HTTP.Namespace),
|
||||
http.Name(options.Config.Service.Name),
|
||||
http.Version(version.String),
|
||||
http.Address(options.Config.HTTP.Addr),
|
||||
http.Context(options.Context),
|
||||
http.Flags(options.Flags...),
|
||||
http.TLSConfig(tlsConfig),
|
||||
)
|
||||
|
||||
handle := svc.NewService(
|
||||
svc.Logger(options.Logger),
|
||||
svc.Config(options.Config),
|
||||
svc.Middleware(
|
||||
chimiddleware.RealIP,
|
||||
chimiddleware.RequestID,
|
||||
middleware.TraceContext,
|
||||
middleware.NoCache,
|
||||
middleware.Secure,
|
||||
middleware.Version(
|
||||
options.Config.Service.Name,
|
||||
version.String,
|
||||
),
|
||||
middleware.Logger(
|
||||
options.Logger,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
{
|
||||
handle = svc.NewInstrument(handle, options.Metrics)
|
||||
handle = svc.NewLoggingHandler(handle, options.Logger)
|
||||
}
|
||||
|
||||
if err := micro.RegisterHandler(service.Server(), handle); err != nil {
|
||||
return http.Service{}, err
|
||||
}
|
||||
|
||||
return service, nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/metrics"
|
||||
)
|
||||
|
||||
// NewInstrument returns a service that instruments metrics.
|
||||
func NewInstrument(next Service, metrics *metrics.Metrics) Service {
|
||||
return instrument{
|
||||
next: next,
|
||||
metrics: metrics,
|
||||
}
|
||||
}
|
||||
|
||||
type instrument struct {
|
||||
next Service
|
||||
metrics *metrics.Metrics
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
func (i instrument) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
i.next.ServeHTTP(w, r)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// NewLogging returns a service that logs messages.
|
||||
func NewLoggingHandler(next Service, logger log.Logger) Service {
|
||||
return loggingHandler{
|
||||
next: next,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
type loggingHandler struct {
|
||||
next Service
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
func (l loggingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
l.next.ServeHTTP(w, r)
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Config *config.Config
|
||||
Middleware []func(http.Handler) http.Handler
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
func newOptions(opts ...Option) Options {
|
||||
opt := Options{}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
// Logger provides a function to set the logger option.
|
||||
func Logger(val log.Logger) Option {
|
||||
return func(o *Options) {
|
||||
o.Logger = val
|
||||
}
|
||||
}
|
||||
|
||||
// Config provides a function to set the config option.
|
||||
func Config(val *config.Config) Option {
|
||||
return func(o *Options) {
|
||||
o.Config = val
|
||||
}
|
||||
}
|
||||
|
||||
// Middleware provides a function to set the middleware option.
|
||||
func Middleware(val ...func(http.Handler) http.Handler) Option {
|
||||
return func(o *Options) {
|
||||
o.Middleware = val
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/libregraph/lico/bootstrap"
|
||||
dummyBackendSupport "github.com/libregraph/lico/bootstrap/backends/dummy"
|
||||
guestBackendSupport "github.com/libregraph/lico/bootstrap/backends/guest"
|
||||
kcBackendSupport "github.com/libregraph/lico/bootstrap/backends/kc"
|
||||
ldapBackendSupport "github.com/libregraph/lico/bootstrap/backends/ldap"
|
||||
licoconfig "github.com/libregraph/lico/config"
|
||||
"github.com/libregraph/lico/server"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/assets"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/middleware"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"stash.kopano.io/kgol/rndm"
|
||||
)
|
||||
|
||||
// Service defines the extension handlers.
|
||||
type Service interface {
|
||||
ServeHTTP(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// NewService returns a service implementation for Service.
|
||||
func NewService(opts ...Option) Service {
|
||||
ctx := context.Background()
|
||||
options := newOptions(opts...)
|
||||
logger := options.Logger.Logger
|
||||
assetVFS := assets.New(
|
||||
assets.Logger(options.Logger),
|
||||
assets.Config(options.Config),
|
||||
)
|
||||
|
||||
if err := initLicoInternalEnvVars(&options.Config.Ldap); err != nil {
|
||||
logger.Fatal().Err(err).Msg("could not initialize env vars")
|
||||
}
|
||||
|
||||
if err := createConfigsIfNotExist(assetVFS, options.Config.IDP.IdentifierRegistrationConf, options.Config.IDP.Iss); err != nil {
|
||||
logger.Fatal().Err(err).Msg("could not create default config")
|
||||
}
|
||||
|
||||
guestBackendSupport.MustRegister()
|
||||
ldapBackendSupport.MustRegister()
|
||||
dummyBackendSupport.MustRegister()
|
||||
kcBackendSupport.MustRegister()
|
||||
|
||||
// https://play.golang.org/p/Mh8AVJCd593
|
||||
idpSettings := bootstrap.Settings(options.Config.IDP)
|
||||
|
||||
bs, err := bootstrap.Boot(ctx, &idpSettings, &licoconfig.Config{
|
||||
Logger: log.LogrusWrap(logger),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logger.Fatal().Err(err).Msg("could not bootstrap idp")
|
||||
}
|
||||
|
||||
managers := bs.Managers()
|
||||
routes := []server.WithRoutes{managers.Must("identity").(server.WithRoutes)}
|
||||
handlers := managers.Must("handler").(http.Handler)
|
||||
|
||||
svc := IDP{
|
||||
logger: options.Logger,
|
||||
config: options.Config,
|
||||
assets: assetVFS,
|
||||
}
|
||||
|
||||
svc.initMux(ctx, routes, handlers, options)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
func createConfigsIfNotExist(assets http.FileSystem, filePath, ocisURL string) error {
|
||||
|
||||
folder := path.Dir(filePath)
|
||||
if _, err := os.Stat(folder); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(folder, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
defaultConf, err := assets.Open("/identifier-registration.yaml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer defaultConf.Close()
|
||||
|
||||
confOnDisk, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer confOnDisk.Close()
|
||||
|
||||
conf, err := ioutil.ReadAll(defaultConf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// replace placeholder {{OCIS_URL}} with https://localhost:9200 / correct host
|
||||
conf = []byte(strings.ReplaceAll(string(conf), "{{OCIS_URL}}", strings.TrimRight(ocisURL, "/")))
|
||||
|
||||
err = ioutil.WriteFile(filePath, conf, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// Init vars which are currently not accessible via idp api
|
||||
func initLicoInternalEnvVars(ldap *config.Ldap) error {
|
||||
filter := fmt.Sprintf("(objectclass=%s)", ldap.ObjectClass)
|
||||
if ldap.Filter != "" {
|
||||
filter = fmt.Sprintf("(&%s%s)", ldap.Filter, filter)
|
||||
}
|
||||
var defaults = map[string]string{
|
||||
"LDAP_URI": ldap.URI,
|
||||
"LDAP_BINDDN": ldap.BindDN,
|
||||
"LDAP_BINDPW": ldap.BindPassword,
|
||||
"LDAP_BASEDN": ldap.BaseDN,
|
||||
"LDAP_SCOPE": ldap.Scope,
|
||||
"LDAP_LOGIN_ATTRIBUTE": ldap.LoginAttribute,
|
||||
"LDAP_EMAIL_ATTRIBUTE": ldap.EmailAttribute,
|
||||
"LDAP_NAME_ATTRIBUTE": ldap.NameAttribute,
|
||||
"LDAP_UUID_ATTRIBUTE": ldap.UUIDAttribute,
|
||||
"LDAP_UUID_ATTRIBUTE_TYPE": ldap.UUIDAttributeType,
|
||||
"LDAP_FILTER": filter,
|
||||
}
|
||||
|
||||
for k, v := range defaults {
|
||||
if err := os.Setenv(k, v); err != nil {
|
||||
return fmt.Errorf("could not set env var %s=%s", k, v)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IDP defines implements the business logic for Service.
|
||||
type IDP struct {
|
||||
logger log.Logger
|
||||
config *config.Config
|
||||
mux *chi.Mux
|
||||
assets http.FileSystem
|
||||
}
|
||||
|
||||
// initMux initializes the internal idp gorilla mux and mounts it in to a ocis chi-router
|
||||
func (idp *IDP) initMux(ctx context.Context, r []server.WithRoutes, h http.Handler, options Options) {
|
||||
gm := mux.NewRouter()
|
||||
for _, route := range r {
|
||||
route.AddRoutes(ctx, gm)
|
||||
}
|
||||
|
||||
// Delegate rest to provider which is also a handler.
|
||||
if h != nil {
|
||||
gm.NotFoundHandler = h
|
||||
}
|
||||
|
||||
idp.mux = chi.NewMux()
|
||||
idp.mux.Use(options.Middleware...)
|
||||
|
||||
idp.mux.Use(middleware.Static(
|
||||
"/signin/v1/",
|
||||
assets.New(
|
||||
assets.Logger(options.Logger),
|
||||
assets.Config(options.Config),
|
||||
),
|
||||
))
|
||||
|
||||
// handle / | index.html with a template that needs to have the BASE_PREFIX replaced
|
||||
idp.mux.Get("/signin/v1/identifier", idp.Index())
|
||||
idp.mux.Get("/signin/v1/identifier/", idp.Index())
|
||||
idp.mux.Get("/signin/v1/identifier/index.html", idp.Index())
|
||||
|
||||
idp.mux.Mount("/", gm)
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
func (idp IDP) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
idp.mux.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// Index renders the static html with the
|
||||
func (idp IDP) Index() http.HandlerFunc {
|
||||
|
||||
f, err := idp.assets.Open("/identifier/index.html")
|
||||
if err != nil {
|
||||
idp.logger.Fatal().Err(err).Msg("Could not open index template")
|
||||
}
|
||||
|
||||
template, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
idp.logger.Fatal().Err(err).Msg("Could not read index template")
|
||||
}
|
||||
if err = f.Close(); err != nil {
|
||||
idp.logger.Fatal().Err(err).Msg("Could not close body")
|
||||
}
|
||||
|
||||
// TODO add environment variable to make the path prefix configurable
|
||||
pp := "/signin/v1"
|
||||
indexHTML := bytes.Replace(template, []byte("__PATH_PREFIX__"), []byte(pp), 1)
|
||||
|
||||
nonce := rndm.GenerateRandomString(32)
|
||||
indexHTML = bytes.Replace(indexHTML, []byte("__CSP_NONCE__"), []byte(nonce), 1)
|
||||
|
||||
indexHTML = bytes.Replace(indexHTML, []byte("__PASSWORD_RESET_LINK__"), []byte(idp.config.Service.PasswordResetURI), 1)
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if _, err := w.Write(indexHTML); err != nil {
|
||||
idp.logger.Error().Err(err).Msg("could not write to response writer")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/middleware"
|
||||
)
|
||||
|
||||
// NewTracing returns a service that instruments traces.
|
||||
func NewTracing(next Service) Service {
|
||||
return tracing{
|
||||
next: next,
|
||||
}
|
||||
}
|
||||
|
||||
type tracing struct {
|
||||
next Service
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
func (t tracing) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
middleware.TraceContext(t.next).ServeHTTP(w, r)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/extensions/idp/pkg/config"
|
||||
pkgtrace "github.com/owncloud/ocis/ocis-pkg/tracing"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
// TraceProvider is the global trace provider for the idp service.
|
||||
TraceProvider = trace.NewNoopTracerProvider()
|
||||
)
|
||||
|
||||
func Configure(cfg *config.Config) error {
|
||||
var err error
|
||||
if cfg.Tracing.Enabled {
|
||||
if TraceProvider, err = pkgtrace.GetTraceProvider(cfg.Tracing.Endpoint, cfg.Tracing.Collector, cfg.Service.Name, cfg.Tracing.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# backend
|
||||
-r '^(cmd|pkg)/.*\.go$' -R '^node_modules/' -s -- sh -c 'make bin/ocis-idp-debug && bin/ocis-idp-debug --log-level debug server --debug-pprof --debug-zpages'
|
||||
@@ -0,0 +1,211 @@
|
||||
'use strict';
|
||||
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.BABEL_ENV = 'production';
|
||||
process.env.NODE_ENV = 'production';
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', err => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../ui_config/env');
|
||||
|
||||
|
||||
const path = require('path');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const fs = require('fs-extra');
|
||||
const webpack = require('webpack');
|
||||
const configFactory = require('../ui_config/webpack.config');
|
||||
const paths = require('../ui_config/paths');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
|
||||
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
|
||||
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
|
||||
const printBuildError = require('react-dev-utils/printBuildError');
|
||||
|
||||
const measureFileSizesBeforeBuild =
|
||||
FileSizeReporter.measureFileSizesBeforeBuild;
|
||||
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
|
||||
// These sizes are pretty large. We'll warn for bundles exceeding them.
|
||||
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
|
||||
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
|
||||
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
// Warn and crash if required files are missing
|
||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Generate configuration
|
||||
const config = configFactory('production');
|
||||
|
||||
// We require that you explicitly set browsers and do not fall back to
|
||||
// browserslist defaults.
|
||||
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
|
||||
checkBrowsers(paths.appPath, isInteractive)
|
||||
.then(() => {
|
||||
// First, read the current file sizes in build directory.
|
||||
// This lets us display how much they changed later.
|
||||
return measureFileSizesBeforeBuild(paths.appBuild);
|
||||
})
|
||||
.then(previousFileSizes => {
|
||||
// Remove all content but keep the directory so that
|
||||
// if you're in it, you don't end up in Trash
|
||||
fs.emptyDirSync(paths.appBuild);
|
||||
// Merge with the public folder
|
||||
copyPublicFolder();
|
||||
// Start the webpack build
|
||||
return build(previousFileSizes);
|
||||
})
|
||||
.then(
|
||||
({ stats, previousFileSizes, warnings }) => {
|
||||
if (warnings.length) {
|
||||
console.log(chalk.yellow('Compiled with warnings.\n'));
|
||||
console.log(warnings.join('\n\n'));
|
||||
console.log(
|
||||
'\nSearch for the ' +
|
||||
chalk.underline(chalk.yellow('keywords')) +
|
||||
' to learn more about each warning.'
|
||||
);
|
||||
console.log(
|
||||
'To ignore, add ' +
|
||||
chalk.cyan('// eslint-disable-next-line') +
|
||||
' to the line before.\n'
|
||||
);
|
||||
} else {
|
||||
console.log(chalk.green('Compiled successfully.\n'));
|
||||
}
|
||||
|
||||
console.log('File sizes after gzip:\n');
|
||||
printFileSizesAfterBuild(
|
||||
stats,
|
||||
previousFileSizes,
|
||||
paths.appBuild,
|
||||
WARN_AFTER_BUNDLE_GZIP_SIZE,
|
||||
WARN_AFTER_CHUNK_GZIP_SIZE
|
||||
);
|
||||
console.log();
|
||||
|
||||
const appPackage = require(paths.appPackageJson);
|
||||
const publicUrl = paths.publicUrl;
|
||||
const publicPath = config.output.publicPath;
|
||||
const buildFolder = path.relative(process.cwd(), paths.appBuild);
|
||||
printHostingInstructions(
|
||||
appPackage,
|
||||
publicUrl,
|
||||
publicPath,
|
||||
buildFolder,
|
||||
useYarn
|
||||
);
|
||||
},
|
||||
err => {
|
||||
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
|
||||
if (tscCompileOnError) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Compiled with the following type errors (you may want to check these before deploying your app):\n'
|
||||
)
|
||||
);
|
||||
printBuildError(err);
|
||||
} else {
|
||||
console.log(chalk.red('Failed to compile.\n'));
|
||||
printBuildError(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
)
|
||||
.catch(err => {
|
||||
if (err && err.message) {
|
||||
console.log(err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Create the production build and print the deployment instructions.
|
||||
function build(previousFileSizes) {
|
||||
// We used to support resolving modules according to `NODE_PATH`.
|
||||
// This now has been deprecated in favor of jsconfig/tsconfig.json
|
||||
// This lets you use absolute paths in imports inside large monorepos:
|
||||
if (process.env.NODE_PATH) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log('Creating an optimized production build...');
|
||||
|
||||
const compiler = webpack(config);
|
||||
return new Promise((resolve, reject) => {
|
||||
compiler.run((err, stats) => {
|
||||
let messages;
|
||||
if (err) {
|
||||
if (!err.message) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
let errMessage = err.message;
|
||||
|
||||
// Add additional information for postcss errors
|
||||
if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) {
|
||||
errMessage +=
|
||||
'\nCompileError: Begins at CSS selector ' +
|
||||
err['postcssNode'].selector;
|
||||
}
|
||||
|
||||
messages = formatWebpackMessages({
|
||||
errors: [errMessage],
|
||||
warnings: [],
|
||||
});
|
||||
} else {
|
||||
messages = formatWebpackMessages(
|
||||
stats.toJson({ all: false, warnings: true, errors: true })
|
||||
);
|
||||
}
|
||||
if (messages.errors.length) {
|
||||
// Only keep the first error. Others are often indicative
|
||||
// of the same problem, but confuse the reader with noise.
|
||||
if (messages.errors.length > 1) {
|
||||
messages.errors.length = 1;
|
||||
}
|
||||
return reject(new Error(messages.errors.join('\n\n')));
|
||||
}
|
||||
if (
|
||||
process.env.CI &&
|
||||
(typeof process.env.CI !== 'string' ||
|
||||
process.env.CI.toLowerCase() !== 'false') &&
|
||||
messages.warnings.length
|
||||
) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'\nTreating warnings as errors because process.env.CI = true.\n' +
|
||||
'Most CI servers set it automatically.\n'
|
||||
)
|
||||
);
|
||||
return reject(new Error(messages.warnings.join('\n\n')));
|
||||
}
|
||||
|
||||
return resolve({
|
||||
stats,
|
||||
previousFileSizes,
|
||||
warnings: messages.warnings,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function copyPublicFolder() {
|
||||
fs.copySync(paths.appPublic, paths.appBuild, {
|
||||
dereference: true,
|
||||
filter: file => file !== paths.appHtml,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
'use strict';
|
||||
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.BABEL_ENV = 'development';
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', err => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../ui_config/env');
|
||||
|
||||
|
||||
const fs = require('fs');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
const clearConsole = require('react-dev-utils/clearConsole');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const {
|
||||
choosePort,
|
||||
createCompiler,
|
||||
prepareProxy,
|
||||
prepareUrls,
|
||||
} = require('react-dev-utils/WebpackDevServerUtils');
|
||||
const openBrowser = require('react-dev-utils/openBrowser');
|
||||
const paths = require('../ui_config/paths');
|
||||
const configFactory = require('../ui_config/webpack.config');
|
||||
const createDevServerConfig = require('../ui_config/webpackDevServer.config');
|
||||
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
// Warn and crash if required files are missing
|
||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Tools like Cloud9 rely on this.
|
||||
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
|
||||
const HOST = process.env.HOST || '0.0.0.0';
|
||||
|
||||
if (process.env.HOST) {
|
||||
console.log(
|
||||
chalk.cyan(
|
||||
`Attempting to bind to HOST environment variable: ${chalk.yellow(
|
||||
chalk.bold(process.env.HOST)
|
||||
)}`
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
|
||||
);
|
||||
console.log(
|
||||
`Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}`
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
// We require that you explicitly set browsers and do not fall back to
|
||||
// browserslist defaults.
|
||||
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
|
||||
checkBrowsers(paths.appPath, isInteractive)
|
||||
.then(() => {
|
||||
// We attempt to use the default port but if it is busy, we offer the user to
|
||||
// run on a different port. `choosePort()` Promise resolves to the next free port.
|
||||
return choosePort(HOST, DEFAULT_PORT);
|
||||
})
|
||||
.then(port => {
|
||||
if (port == null) {
|
||||
// We have not found a port.
|
||||
return;
|
||||
}
|
||||
const config = configFactory('development');
|
||||
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
|
||||
const appName = require(paths.appPackageJson).name;
|
||||
const useTypeScript = fs.existsSync(paths.appTsConfig);
|
||||
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
|
||||
const urls = prepareUrls(protocol, HOST, port);
|
||||
const devSocket = {
|
||||
warnings: warnings =>
|
||||
devServer.sockWrite(devServer.sockets, 'warnings', warnings),
|
||||
errors: errors =>
|
||||
devServer.sockWrite(devServer.sockets, 'errors', errors),
|
||||
};
|
||||
// Create a webpack compiler that is configured with custom messages.
|
||||
const compiler = createCompiler({
|
||||
appName,
|
||||
config,
|
||||
devSocket,
|
||||
urls,
|
||||
useYarn,
|
||||
useTypeScript,
|
||||
tscCompileOnError,
|
||||
webpack,
|
||||
});
|
||||
// Load proxy config
|
||||
const proxySetting = require(paths.appPackageJson).proxy;
|
||||
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
|
||||
// Serve webpack assets generated by the compiler over a web server.
|
||||
const serverConfig = createDevServerConfig(
|
||||
proxyConfig,
|
||||
urls.lanUrlForConfig
|
||||
);
|
||||
const devServer = new WebpackDevServer(compiler, serverConfig);
|
||||
// Launch WebpackDevServer.
|
||||
devServer.listen(port, HOST, err => {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
}
|
||||
if (isInteractive) {
|
||||
clearConsole();
|
||||
}
|
||||
|
||||
// We used to support resolving modules according to `NODE_PATH`.
|
||||
// This now has been deprecated in favor of jsconfig/tsconfig.json
|
||||
// This lets you use absolute paths in imports inside large monorepos:
|
||||
if (process.env.NODE_PATH) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log(chalk.cyan('Starting the development server...\n'));
|
||||
openBrowser(urls.localUrlForBrowser);
|
||||
});
|
||||
|
||||
['SIGINT', 'SIGTERM'].forEach(function(sig) {
|
||||
process.on(sig, function() {
|
||||
devServer.close();
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
if (err && err.message) {
|
||||
console.log(err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
'use strict';
|
||||
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.BABEL_ENV = 'test';
|
||||
process.env.NODE_ENV = 'test';
|
||||
process.env.PUBLIC_URL = '';
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', err => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../ui_config/env');
|
||||
|
||||
|
||||
const jest = require('jest');
|
||||
const execSync = require('child_process').execSync;
|
||||
let argv = process.argv.slice(2);
|
||||
|
||||
function isInGitRepository() {
|
||||
try {
|
||||
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isInMercurialRepository() {
|
||||
try {
|
||||
execSync('hg --cwd . root', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Watch unless on CI or explicitly running all tests
|
||||
if (
|
||||
!process.env.CI &&
|
||||
argv.indexOf('--watchAll') === -1 &&
|
||||
argv.indexOf('--watchAll=false') === -1
|
||||
) {
|
||||
// https://github.com/facebook/create-react-app/issues/5210
|
||||
const hasSourceControl = isInGitRepository() || isInMercurialRepository();
|
||||
argv.push(hasSourceControl ? '--watch' : '--watchAll');
|
||||
}
|
||||
|
||||
|
||||
jest.run(argv);
|
||||
@@ -0,0 +1,52 @@
|
||||
# Tools
|
||||
|
||||
YARN ?= yarn
|
||||
MSGMERGE ?= msgmerge
|
||||
MSGFMT ?= msgfmt
|
||||
|
||||
# Variables
|
||||
|
||||
POT = konnect-identifier.pot
|
||||
POS = $(wildcard *.po)
|
||||
|
||||
# Translations
|
||||
|
||||
.PHONY: build
|
||||
build: json
|
||||
|
||||
.PHONY: extract
|
||||
extract: pot
|
||||
|
||||
.PHONY: i18n/src/messages.json
|
||||
i18n/src/messages.json:
|
||||
$(YARN) react-intl-cra './src/**/*.{js,jsx}' -o $@
|
||||
|
||||
.PHONY: pot
|
||||
pot: i18n/src/messages.json
|
||||
$(YARN) rip json2pot './i18n/src/**/*.json' \
|
||||
-o ./i18n/$(POT) \
|
||||
-c 'id'
|
||||
|
||||
.PHONY: json
|
||||
json: i18n/src/messages.json
|
||||
$(YARN) rip po2json './i18n/*.po' \
|
||||
-m './i18n/src/**/*.json' \
|
||||
-o './src/locales/' \
|
||||
-c 'id' \
|
||||
--indentation=2
|
||||
|
||||
.PHONY: merge
|
||||
merge: $(POS)
|
||||
|
||||
.PHONY: stats
|
||||
stats:
|
||||
$(foreach po, $(POS), $(shell $(MSGFMT) -v --statistics $(po)))
|
||||
@- true
|
||||
|
||||
$(POS): FORCE $(POT)
|
||||
$(MSGMERGE) -U \
|
||||
--backup=none \
|
||||
--no-wrap \
|
||||
$@ $(POT)
|
||||
|
||||
FORCE:
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2019-05-08 18:23+0200\n"
|
||||
"Last-Translator: Simon Eisenmann <simon@longsleep.org>\n"
|
||||
"Language-Team: German <http://translate.kopano.io/projects/kopano/konnect/de/>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Poedit 1.8.7.1\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr "Zugriff auf Ihre grundlegenden Benutzerinformationen"
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr "Einverstanden"
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr "{clientDisplayName} den Zugriff gestatten?"
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr "Wenn Sie Einverstanden klicken, erhält die App Zugriff auf Ihre Informationen."
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr "Konto auswählen"
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr "Wenn Sie \"Einverstanden\" klicken werden Sie zu {redirectURI} weitergeleitet"
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr "Geben Sie ein Passwort ein"
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr "Geben Sie einen Benutzername ein"
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Verbindung zum Server fehlgeschlagen"
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr "Bis bald"
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr "Hallo {displayName}"
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr "Hi {displayName}"
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr "Dauerhaften Zugriff (läuft nicht ab)"
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr "Anmeldung fehlgeschlagen. Bitte überprüfen Sie Ihre Eingabe und versuchen Sie es noch einmal."
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr "Netzwerkfehler. Bitte prüfen Sie Ihre Verbindung und versuchen Sie es noch einmal."
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr "Weiter"
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr "Klicken Sie auf die Schaltfläche unten um sich aus Ihrem Kopano Konto abzumelden."
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr "Wiederholen"
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr "Geltungsbereich: {scope}"
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Abmelden"
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Abmelden"
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr "Unerwartete HTTP-Antwort: {status}. Bitte prüfen Sie Ihre Verbindung und versuchen Sie es noch einmal."
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr "Unerwarteter Antwort-Status: {state}"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr "Anderes Konto"
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr "Benutzername"
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr "Willkommen {displayName}"
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr "Sie sind angemeldet - super!"
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr "Sie können dieses Fenster jetzt schließen."
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr "Bitte bestätigen Sie, dass Sie sich abmelden möchten"
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr "um sich bei Kopano anzumelden"
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr "mit Ihrem Kopano Konto"
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr "sie sind jetzt von Ihrem Kopano Konto abgemeldet"
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr "{clientDisplayName} möchte"
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2018-10-30T16:08:29.860Z\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: react-intl-po\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2019-08-26 15:43+0000\n"
|
||||
"Last-Translator: Dominique <dperessoni@alternatiq.com>\n"
|
||||
"Language-Team: French <http://translate.kopano.io/projects/kopano/konnect/fr/>\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 2.4\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr "Consulter les informations de base de votre compte"
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr "Autoriser"
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr "Autoriser {clientDisplayName} à faire cela ?"
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr "En cliquant, vous autoriser l'app à accéder à vos informations."
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr "Choisir un compte"
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr "En cliquant \"Autoriser\" vous serez redirigé vers : {redirectURI}"
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr "Saisir un mot de passe"
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr "Saisir un identifiant"
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "La connexion au serveur a échoué"
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr "Au revoir"
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr "Bonjour {displayName}"
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr "Bonjour {displayName}"
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr "Conserver les autorisations d'accès à l'avenir"
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr "Echec de connexion. Vérifier vos identifiants et essayer à nouveau."
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr "Erreur réseau. Vérifier votre connexion, et réessayer."
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr "Suivant"
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr "Mot de passe"
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr "Cliquer le bouton ci-dessous, pour quitter Kopano."
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr "Réessayer"
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr "Portée : {scope}"
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr "Identification"
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Quitter"
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Quitter"
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr "Erreur HTTP inattendue : {status}. Vérifier votre connexion et réessayer."
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr "Erreur d'état inattendue : {state}"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr "Utiliser un autre compte"
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr "Utilisateur"
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr "Bienvenue {displayName}"
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr "Magnifique - Vous êtes connecté !"
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr "Vous pouvez fermer cette fenêtre à présent."
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr "Confirmer votre déconnexion"
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr "pour vous authentifier dans Kopano"
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr "avec vos identifiants Kopano"
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr "vous avez été déconnecté de Kopano"
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr "{clientDisplayName} souhaite"
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2019-09-04 09:55+0000\n"
|
||||
"Last-Translator: Mayank <m.dabhi@kopano.com>\n"
|
||||
"Language-Team: Hindi <http://translate.kopano.io/projects/kopano/konnect/hi/>\n"
|
||||
"Language: hi\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2.4\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr "अपनी मूल खाता जानकारी देखे"
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr "अनुमति दीजिये"
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr "क्या {clientDisplayName} को ये करने की अनुमति देना चाहते है?"
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr "अनुमति पर क्लिक करके, आप इस एप्लिकेशन को आपकी जानकारी का उपयोग करने की अनुमति देते हैं."
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr "रद्द करें"
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr "खाता चुनें"
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr "\"अनुमति\" पर क्लिक करने से आपको {redirecturI} पे पुनर्निर्देशित किया जायेगा"
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr "पासवर्ड डालिए"
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr "उपयोगकर्ता नाम डालिये"
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "सर्वर से कनेक्ट करने में विफल"
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr "अलविदा"
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr "नमस्ते {displayName}"
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr "नमस्ते {displayName}"
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr "अनुमत पहुंच को लगातार और हमेशा बनाए रखें"
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr "लोगऑन नाकाम रहा. कृपया अपने क्रेडेंशियल्स जांचे और पुनः प्रयास करें."
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr "नेटवर्क त्रुटि। कृपया अपने संपर्क की जांच करे और फिर से प्रयास करें."
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr "अगला"
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr "पासवर्ड"
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr "अपने Kopano खाते से साइन आउट करने के लिए नीचे दिए गए बटन को दबाएं."
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr "पुन: प्रयास करें"
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr "क्षेत्र: {scope}"
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr "साइन इन"
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "साइन आउट"
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "साइन आउट"
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr "अनपेक्षित HTTP प्रतिक्रिया: {status}. कृपया अपने संपर्क की जांच करे और फिर से प्रयास करें."
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr "अनपेक्षित प्रतिक्रिया अवस्था: {state}"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr "दूसरे खाते का उपयोग करें"
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr "उपयोगकर्ता नाम"
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr "स्वागत हे {displayName}"
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr "आप साइंड इन हैं - अद्भुत!"
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr "अब आप इस विंडो को बंद कर सकते हैं."
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr "कृपया साइन आउट की पुष्टि करें"
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr "Kopano में साइन इन करने के लिए"
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr "अपने Kopano खाते के साथ"
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr "आपको अपने Kopano खाते से साइन आउट कर दिया गया है"
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr "{clientDisplayName} चाहते है की"
|
||||
@@ -0,0 +1,310 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"X-Generator: react-intl-po\n"
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"PO-Revision-Date: 2019-08-30 11:41+0200\n"
|
||||
"Last-Translator: root <translations@kopano.io>\n"
|
||||
"Language-Team: Croatian\n"
|
||||
"Language: hr\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2018-10-30T16:08:29.860Z\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: hu\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: react-intl-po\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2019-09-02 15:40+0000\n"
|
||||
"Last-Translator: Tryggvi Björgvinsson <ME@TRICKVI.IS>\n"
|
||||
"Language-Team: Icelandic <http://translate.kopano.io/projects/kopano/konnect/is/>\n"
|
||||
"Language: is\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2.4\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr "Komast í grunnupplýsingar um þig"
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr "Leyfa"
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr "Leyfa {clientDisplayName} að gera þetta?"
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr "Með því að smella á \"Leyfa\", leyfir þú þessu forriti að nota upplýsingarnar um þig."
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr "Hætta við"
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr "Veldu aðgang"
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr "Þegar þú smellir á \"Leyfa\" áframsendist þú á: {redirectURI}"
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr "Sláðu inn lykilorð"
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr "Sláðu inn notandanafn"
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Mistókst að tengjast netþjóni"
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr "Bless"
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr "Halló {displayName}"
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr "Hæ {displayName}"
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr "Viðhalda heimildunum alltaf og að eilífu (mundu mig)"
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr "Innskráning mistókst. Vinsamlegast staðfestu notandaupplýsingarnar og reyndu aftur."
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr "Netvilla. Vinsamlegast athugaðu tenginguna þína og reyndu aftur."
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr "Næsta"
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr "Lykilorð"
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr "Smelltu á takkann fyrir neðan til að skrá þig út af Kopano aðganginum núna."
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr "Reyna aftur"
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr "Gildissvið: {scope}"
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr "Innskrá"
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Útskrá"
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Útskrá"
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr "Ófyrirsjáanlegt HTTP svar: {status}. Vinsamlegast athugaðu tenginguna þína og reyndu aftur."
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr "Ófyrirsjáanleg svarstaða: {state}"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr "Nota annan aðgang"
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr "Notandanafn"
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr "Halló {displayName}"
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr "Innskráningin tókst - frábært!"
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr "Þú getur lokað þessum glugga núna."
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr "vinsamlegast staðfestu útskráningu"
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr "til að skrá þig inn í Kopano"
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr "með Kopano-aðganginum þínum"
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr "útskráning Kopano-aðgangsins þíns tókst"
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr "{clientDisplayName} vill"
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2018-10-30T16:08:29.860Z\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: react-intl-po\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2018-10-30T16:08:29.860Z\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: ja\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: react-intl-po\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,304 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"X-Generator: react-intl-po\n"
|
||||
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#: ./i18n/src/messages.json
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2019-08-26 16:21+0000\n"
|
||||
"Last-Translator: Klaus <klaus@linuxavdelingen.no>\n"
|
||||
"Language-Team: Norwegian Bokmål <http://translate.kopano.io/projects/kopano/konnect/nb/>\n"
|
||||
"Language: nb\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2.4\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr "Tilgang til informasjon om basiskonto"
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr "Tillat"
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr "Tillatt {clientDisplayName} å gjøre dette?"
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr "Ved å klikke på Aksepter, så tillater du at appen bruker din informasjon."
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr "Velg en konto"
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr "Ved å klikke på \"Tillatt\" så vil du bli ledet til: {redirectURI}"
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr "Skriv inn et passord"
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr "Skriv inn et brukernavn"
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Klarte ikke å forbinde med server"
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr "Farvel"
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr "Hallo {displayName}"
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr "Hei {displayName}"
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr "Behold den tillate tilgangen for alltid"
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr "Logg inn feilet. Vennligst sjekk brukernavn/passord, og forsøk igjen."
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr "Nettverksfeil. Sjekk din forbindelse, og forsøk igjen."
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr "Neste"
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr "Passord"
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr "Trykk på knappen under, for å logge ut av din Kopano konto."
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr "Prøv igjen"
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr "Omfang: {scope}"
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr "Logg inn"
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Logg ut"
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Logg ut"
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr "Uventet HTTP respons: {status}. Sjekk tilkoblingen din og prøv igjen."
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr "Uventet svar-status: {state}"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr "Bruk en annen konto"
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr "Brukernavn"
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr "Velkommen {displayName}"
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr "Du er logget på!"
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr "Du kan lukke dette vinduet nå."
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr "vennligst bekreft utlogging"
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr "for å logge inn i Kopano"
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr "med din Kopano konto"
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr "du har blitt logget ut fra din Kopano konto"
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr "{clientDisplayName} ønsker"
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2019-05-09 13:19+0000\n"
|
||||
"Last-Translator: Bob <b.huisman@kopano.com>\n"
|
||||
"Language-Team: Dutch <http://translate.kopano.io/projects/kopano/konnect/nl/>\n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 2.4\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr "Basis accountgegevens weergeven"
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr "Toestaan"
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr "{clientDisplayName} toestaan dit te doen?"
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr "Door op Toestaan te klikken, krijgt deze app toestemming je informatie te gebruiken."
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleren"
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr "Account kiezen"
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr "Door op \"Toestaan\" te klikken word je doorverwezen naar: {redirectURI}"
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr "Voer een wachtwoord in"
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr "Voer een gebruikersnaam in"
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Kon niet met server verbinden"
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr "Tot ziens"
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr "Hallo {displayName}"
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr "Hoi {displayName}"
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr "De toestemming voor altijd onthouden"
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr "Inloggen mislukt. Controleer logingegevens en probeer opnieuw."
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr "Netwerk probleem. Controleer je verbinding en probeer opnieuw."
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr "Volgende"
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr "Wachtwoord"
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr "Klik op onderstaande knop om af te melden van je Kopano account."
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr "Opnieuw"
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr "Scope: {scope}"
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr "Aanmelden"
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Afmelden"
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Afmelden"
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr "Onverwachte HTTP respons: {status}. Controleer je verbinding en probeer opnieuw."
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr "Onverwachte respons status: {state}"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr "Gebruik een ander account"
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr "Gebruikersnaam"
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr "Welkom {displayName}"
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr "Je bent aangemeld - fantastisch!"
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr "Dit venster kan nu worden gesloten."
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr "bevestig afmelden"
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr "om aan te melden bij Kopano"
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr "met je Kopano account"
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr "je bent afgemeld van je Kopano account"
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr "{clientDisplayName} wil"
|
||||
@@ -0,0 +1,308 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"X-Generator: react-intl-po\n"
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"PO-Revision-Date: 2019-08-30 11:45+0200\n"
|
||||
"Last-Translator: root <root@podo.kopano.io>\n"
|
||||
"Language-Team: Language po\n"
|
||||
"Language: po\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2019-05-31 09:39+0000\n"
|
||||
"Last-Translator: Nuno Jerónimo <nuno.jeronimo@valsousa.pt>\n"
|
||||
"Language-Team: Portuguese (Portugal) <http://translate.kopano.io/projects/kopano/konnect/pt_PT/>\n"
|
||||
"Language: pt_PT\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 2.4\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr "Aceder à sua informação básica da conta"
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr "Permitir"
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr "Permitir que {clientDisplayName} faça isto?"
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr "Ao carregar em Permitir, está a permitir que esta app use os seus dados."
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr "Escolher uma conta"
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr "Ao carregar em \"Permitir\" será redirecionado para: {redirectURI}"
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr "Insira uma palavra-passe"
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr "Insira um utilizador"
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Falhou a ligar ao servidor"
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr "Adeus"
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr "Olá {displayName}"
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr "Olá {displayName}"
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr "Manter o acesso permitido de forma persistente e para sempre"
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr "Falhou início de sessão. Por favor verifique as suas credenciais e tente novamente."
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr "Erro de rede. Por favor verifique as ligações e tente novamente."
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr "Seguinte"
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr "Palavra-passe"
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr "Carregue no botão abaixo para terminar sessão na sua conta Kopano agora."
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr "Tentar novamente"
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr "Contexto: {scope}"
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr "Iniciar sessão"
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Terminar sessão"
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Terminar sessão"
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr "Resposta HTTP inesperada: {status}. Por favor verifique a sua ligação e tente novamente."
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr "Resposta de estado inesperada: {state}"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr "Use outra conta"
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr "Utilizador"
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr "Bem vindo {displayName}"
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr "Iniciou sessão - fantástico!"
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr "Pode fechar esta janela agora."
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr "por favor confirme o fim de sessão"
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr "para iniciar sessão no Kopano"
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr "com a sua conta Kopano"
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr "a sessão da sua conta Kopano foi terminada"
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr "{clientDisplayName} quer"
|
||||
@@ -0,0 +1,309 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"PO-Revision-Date: 2019-08-27 08:46+0000\n"
|
||||
"Last-Translator: Sotneo <kerovsot@gmail.com>\n"
|
||||
"Language-Team: Russian <http://translate.kopano.io/projects/kopano/konnect/ru/>\n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 2.4\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr "?"
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr "Доступ к вашей основной учетной записи"
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr "Разрешить"
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr "Разрешить {clientDisplayName} сделать это?"
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr "Нажимая Разрешить, ты даёте разрешение этому приложению использовать вашу информацию."
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr "Выберите учётную запись"
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr "После нажатия \"Разрешить\" вы будете перенаправлена на: {redirectURI}"
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr "Введите пароль"
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr "Введите имя пользователя"
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Не удалось подключиться к серверу"
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr "До свидания"
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr "Здравствуйте, {displayName}"
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr "Привет, {displayName}"
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr "Сохраните разрешение на доступ как постоянное"
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr "Не удалось войти. Пожалуйста, проверьте ваши учетные данные и попробуйте снова."
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr "Сетевая ошибка. Пожалуйста, проверьте ваше соединение и попробуйте снова."
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr "Далее"
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr "Пароль"
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr "Нажмите кнопку ниже, чтобы выйти из вашей учетной записи Kopano."
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr "Повторить"
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr "Охват: {scope}"
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr "Вход"
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Выход"
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr "Выход"
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr "Неожиданный ответ HTTP: {status}. Проверьте подключение и повторите попытку."
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr "Неожиданный ответ: {state}"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr "Другой пользователь"
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr "Имя пользователя"
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr "Добро пожаловать, {displayName}"
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr "Вы вошли - круто!"
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr "Теперь вы можете закрыть окно."
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr "пожалуйста, подтвердите выход"
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr "для входа в Kopano"
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr "с вашей учётной записью Kopano"
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr "вы вышли из вашей учетной записи Kopano"
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr "{clientDisplayName} хочет"
|
||||
@@ -0,0 +1,310 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2019-05-09T14:09:27.715Z\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"X-Generator: react-intl-po\n"
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"PO-Revision-Date: 2019-08-30 11:46+0200\n"
|
||||
"Last-Translator: root <root@transdoc.kopano.io>\n"
|
||||
"Language-Team: Slovenian\n"
|
||||
"Language: sl\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
|
||||
"%100==4 ? 2 : 3);\n"
|
||||
|
||||
#. [konnect.chooseaccount.useOther.persona.label]
|
||||
#. defaultMessage is:
|
||||
#. ?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.persona.label"
|
||||
msgid "?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.aliasBasic]
|
||||
#. defaultMessage is:
|
||||
#. Access your basic account information
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.aliasBasic"
|
||||
msgid "Access your basic account information"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.allowButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Allow
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.allowButton.label"
|
||||
msgid "Allow"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.question]
|
||||
#. defaultMessage is:
|
||||
#. Allow {clientDisplayName} to do this?
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.question"
|
||||
msgid "Allow {clientDisplayName} to do this?"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.consequence]
|
||||
#. defaultMessage is:
|
||||
#. By clicking Allow, you allow this app to use your information.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.consequence"
|
||||
msgid "By clicking Allow, you allow this app to use your information."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.cancelButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Cancel
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.cancelButton.label"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.headline]
|
||||
#. defaultMessage is:
|
||||
#. Choose an account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.headline"
|
||||
msgid "Choose an account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.tooltip.client]
|
||||
#. defaultMessage is:
|
||||
#. Clicking "Allow" will redirect you to: {redirectURI}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.tooltip.client"
|
||||
msgid "Clicking \"Allow\" will redirect you to: {redirectURI}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingPassword]
|
||||
#. defaultMessage is:
|
||||
#. Enter a password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingPassword"
|
||||
msgid "Enter a password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.validate.missingUsername]
|
||||
#. defaultMessage is:
|
||||
#. Enter an username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.validate.missingUsername"
|
||||
msgid "Enter an username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.loading.error.headline]
|
||||
#. defaultMessage is:
|
||||
#. Failed to connect to server
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.loading.error.headline"
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.headline]
|
||||
#. defaultMessage is:
|
||||
#. Goodbye
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.headline"
|
||||
msgid "Goodbye"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hello {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.headline"
|
||||
msgid "Hello {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.headline]
|
||||
#. defaultMessage is:
|
||||
#. Hi {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.headline"
|
||||
msgid "Hi {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.offlineAccess]
|
||||
#. defaultMessage is:
|
||||
#. Keep the allowed access persistently and forever
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.offlineAccess"
|
||||
msgid "Keep the allowed access persistently and forever"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.login.failed]
|
||||
#. defaultMessage is:
|
||||
#. Logon failed. Please verify your credentials and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.login.failed"
|
||||
msgid "Logon failed. Please verify your credentials and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnet.error.http.networkError]
|
||||
#. defaultMessage is:
|
||||
#. Network error. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnet.error.http.networkError"
|
||||
msgid "Network error. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.nextButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Next
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.nextButton.label"
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.passwordField.label]
|
||||
#. defaultMessage is:
|
||||
#. Password
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.passwordField.label"
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.confirm]
|
||||
#. defaultMessage is:
|
||||
#. Press the button below, to sign out from your Kopano account now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.confirm"
|
||||
msgid "Press the button below, to sign out from your Kopano account now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.retryButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Retry
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.retryButton.label"
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.scopeDescription.scope]
|
||||
#. defaultMessage is:
|
||||
#. Scope: {scope}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.scopeDescription.scope"
|
||||
msgid "Scope: {scope}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.headline]
|
||||
#. defaultMessage is:
|
||||
#. Sign in
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.headline"
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.signoutButton.label]
|
||||
#. defaultMessage is:
|
||||
#. Sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.signoutButton.label"
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseStatus]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected HTTP response: {status}. Please check your connection and try again.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseStatus"
|
||||
msgid "Unexpected HTTP response: {status}. Please check your connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.error.http.unexpectedResponseState]
|
||||
#. defaultMessage is:
|
||||
#. Unexpected response state: {state}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.error.http.unexpectedResponseState"
|
||||
msgid "Unexpected response state: {state}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.useOther.label]
|
||||
#. defaultMessage is:
|
||||
#. Use another account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.useOther.label"
|
||||
msgid "Use another account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.usernameField.label]
|
||||
#. defaultMessage is:
|
||||
#. Username
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.usernameField.label"
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.headline]
|
||||
#. defaultMessage is:
|
||||
#. Welcome {displayName}
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.headline"
|
||||
msgid "Welcome {displayName}"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.welcome.message]
|
||||
#. defaultMessage is:
|
||||
#. You are signed in - awesome!
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.welcome.message"
|
||||
msgid "You are signed in - awesome!"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.message.close]
|
||||
#. defaultMessage is:
|
||||
#. You can close this window now.
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.message.close"
|
||||
msgid "You can close this window now."
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.confirm.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. please confirm sign out
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.confirm.subHeader"
|
||||
msgid "please confirm sign out"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.chooseaccount.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. to sign in to Kopano
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.chooseaccount.subHeader"
|
||||
msgid "to sign in to Kopano"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.login.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. with your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.login.subHeader"
|
||||
msgid "with your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.goodbye.subHeader]
|
||||
#. defaultMessage is:
|
||||
#. you have been signed out from your Kopano account
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.goodbye.subHeader"
|
||||
msgid "you have been signed out from your Kopano account"
|
||||
msgstr ""
|
||||
|
||||
#. [konnect.consent.message]
|
||||
#. defaultMessage is:
|
||||
#. {clientDisplayName} wants to
|
||||
#: i18n/src/messages.json
|
||||
msgctxt "konnect.consent.message"
|
||||
msgid "{clientDisplayName} wants to"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,187 @@
|
||||
[
|
||||
{
|
||||
"id": "konnect.loading.error.headline",
|
||||
"defaultMessage": "Failed to connect to server",
|
||||
"filepath": "./src/components/Loading.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.login.retryButton.label",
|
||||
"defaultMessage": "Retry",
|
||||
"filepath": "./src/components/Loading.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.scopeDescription.aliasBasic",
|
||||
"defaultMessage": "Access your basic account information",
|
||||
"filepath": "./src/components/ScopesList.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.scopeDescription.offlineAccess",
|
||||
"defaultMessage": "Keep the allowed access persistently and forever",
|
||||
"filepath": "./src/components/ScopesList.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.scopeDescription.scope",
|
||||
"defaultMessage": "Scope: {scope}",
|
||||
"filepath": "./src/components/ScopesList.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.goodbye.headline",
|
||||
"defaultMessage": "Goodbye",
|
||||
"filepath": "./src/containers/Goodbye/Goodbyescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.goodbye.subHeader",
|
||||
"defaultMessage": "you have been signed out from your Kopano account",
|
||||
"filepath": "./src/containers/Goodbye/Goodbyescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.goodbye.message.close",
|
||||
"defaultMessage": "You can close this window now.",
|
||||
"filepath": "./src/containers/Goodbye/Goodbyescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.goodbye.confirm.headline",
|
||||
"defaultMessage": "Hello {displayName}",
|
||||
"filepath": "./src/containers/Goodbye/Goodbyescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.goodbye.confirm.subHeader",
|
||||
"defaultMessage": "please confirm sign out",
|
||||
"filepath": "./src/containers/Goodbye/Goodbyescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.goodbye.message.confirm",
|
||||
"defaultMessage": "Press the button below, to sign out from your Kopano account now.",
|
||||
"filepath": "./src/containers/Goodbye/Goodbyescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.goodbye.signoutButton.label",
|
||||
"defaultMessage": "Sign out",
|
||||
"filepath": "./src/containers/Goodbye/Goodbyescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.chooseaccount.headline",
|
||||
"defaultMessage": "Choose an account",
|
||||
"filepath": "./src/containers/Login/Chooseaccount.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.chooseaccount.subHeader",
|
||||
"defaultMessage": "to sign in to Kopano",
|
||||
"filepath": "./src/containers/Login/Chooseaccount.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.chooseaccount.useOther.persona.label",
|
||||
"defaultMessage": "?",
|
||||
"filepath": "./src/containers/Login/Chooseaccount.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.chooseaccount.useOther.label",
|
||||
"defaultMessage": "Use another account",
|
||||
"filepath": "./src/containers/Login/Chooseaccount.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.consent.headline",
|
||||
"defaultMessage": "Hi {displayName}",
|
||||
"filepath": "./src/containers/Login/Consent.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.consent.message",
|
||||
"defaultMessage": "{clientDisplayName} wants to",
|
||||
"filepath": "./src/containers/Login/Consent.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.consent.tooltip.client",
|
||||
"defaultMessage": "Clicking \"Allow\" will redirect you to: {redirectURI}",
|
||||
"filepath": "./src/containers/Login/Consent.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.consent.question",
|
||||
"defaultMessage": "Allow {clientDisplayName} to do this?",
|
||||
"filepath": "./src/containers/Login/Consent.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.consent.consequence",
|
||||
"defaultMessage": "By clicking Allow, you allow this app to use your information.",
|
||||
"filepath": "./src/containers/Login/Consent.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.consent.cancelButton.label",
|
||||
"defaultMessage": "Cancel",
|
||||
"filepath": "./src/containers/Login/Consent.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.consent.allowButton.label",
|
||||
"defaultMessage": "Allow",
|
||||
"filepath": "./src/containers/Login/Consent.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.login.headline",
|
||||
"defaultMessage": "Sign in",
|
||||
"filepath": "./src/containers/Login/Login.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.login.subHeader",
|
||||
"defaultMessage": "with your Kopano account",
|
||||
"filepath": "./src/containers/Login/Login.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.login.usernameField.label",
|
||||
"defaultMessage": "Username",
|
||||
"filepath": "./src/containers/Login/Login.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.login.passwordField.label",
|
||||
"defaultMessage": "Password",
|
||||
"filepath": "./src/containers/Login/Login.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.login.nextButton.label",
|
||||
"defaultMessage": "Next",
|
||||
"filepath": "./src/containers/Login/Login.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.welcome.headline",
|
||||
"defaultMessage": "Welcome {displayName}",
|
||||
"filepath": "./src/containers/Welcome/Welcomescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.welcome.message",
|
||||
"defaultMessage": "You are signed in - awesome!",
|
||||
"filepath": "./src/containers/Welcome/Welcomescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.welcome.signoutButton.label",
|
||||
"defaultMessage": "Sign out",
|
||||
"filepath": "./src/containers/Welcome/Welcomescreen.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.error.login.validate.missingUsername",
|
||||
"defaultMessage": "Enter an username",
|
||||
"filepath": "./src/errors/index.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.error.login.validate.missingPassword",
|
||||
"defaultMessage": "Enter a password",
|
||||
"filepath": "./src/errors/index.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.error.login.failed",
|
||||
"defaultMessage": "Logon failed. Please verify your credentials and try again.",
|
||||
"filepath": "./src/errors/index.js"
|
||||
},
|
||||
{
|
||||
"id": "konnet.error.http.networkError",
|
||||
"defaultMessage": "Network error. Please check your connection and try again.",
|
||||
"filepath": "./src/errors/index.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.error.http.unexpectedResponseStatus",
|
||||
"defaultMessage": "Unexpected HTTP response: {status}. Please check your connection and try again.",
|
||||
"filepath": "./src/errors/index.js"
|
||||
},
|
||||
{
|
||||
"id": "konnect.error.http.unexpectedResponseState",
|
||||
"defaultMessage": "Unexpected response state: {state}",
|
||||
"filepath": "./src/errors/index.js"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#1b223d">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon.ico" type="image/x-icon">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600&display=swap" rel="stylesheet">
|
||||
<meta property="csp-nonce" content="__CSP_NONCE__">
|
||||
<title>Sign in - ownCloud</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<main id="root" class="oc-login-bg" data-path-prefix="__PATH_PREFIX__" passwort-reset-link="__PASSWORD_RESET_LINK__"></main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="cloud" class="svg-inline--fa fa-cloud fa-w-20" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="#ffffff" d="M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z"></path></svg>
|
||||
|
After Width: | Height: | Size: 479 B |
@@ -0,0 +1,45 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
|
||||
import Routes from './Routes';
|
||||
|
||||
class App extends PureComponent {
|
||||
render() {
|
||||
const { classes, hello, pathPrefix } = this.props;
|
||||
|
||||
return (
|
||||
<BrowserRouter basename={pathPrefix}>
|
||||
<Routes hello={hello}/>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
|
||||
reload(event) {
|
||||
event.preventDefault();
|
||||
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
App.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
hello: PropTypes.object,
|
||||
updateAvailable: PropTypes.bool.isRequired,
|
||||
pathPrefix: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { hello, updateAvailable, pathPrefix } = state.common;
|
||||
|
||||
return {
|
||||
hello,
|
||||
updateAvailable,
|
||||
pathPrefix
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(App);
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import store from './store';
|
||||
import App from './Main';
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<Provider store={store}><App/></Provider>, div);
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import AsyncComponent from 'kpop/es/AsyncComponent';
|
||||
|
||||
import PrivateRoute from './components/PrivateRoute';
|
||||
|
||||
const AsyncLogin = AsyncComponent(() =>
|
||||
import(/* webpackChunkName: "containers-login" */ './containers/Login'));
|
||||
const AsyncWelcome = AsyncComponent(() =>
|
||||
import(/* webpackChunkName: "containers-welcome" */ './containers/Welcome'));
|
||||
const AsyncGoodbye = AsyncComponent(() =>
|
||||
import(/* webpackChunkName: "containers-goodbye" */ './containers/Goodbye'));
|
||||
|
||||
const Routes = ({ hello }) => (
|
||||
<Switch>
|
||||
<PrivateRoute
|
||||
path="/welcome"
|
||||
exact
|
||||
component={AsyncWelcome}
|
||||
hello={hello}
|
||||
/>
|
||||
<Route
|
||||
path="/goodbye"
|
||||
exact
|
||||
component={AsyncGoodbye}
|
||||
/>
|
||||
<Route
|
||||
path="/"
|
||||
component={AsyncLogin}
|
||||
/>
|
||||
</Switch>
|
||||
);
|
||||
|
||||
Routes.propTypes = {
|
||||
hello: PropTypes.object
|
||||
};
|
||||
|
||||
export default Routes;
|
||||
@@ -0,0 +1,133 @@
|
||||
import axios from 'axios';
|
||||
|
||||
import { newHelloRequest } from '../models/hello';
|
||||
import { withClientRequestState } from '../utils';
|
||||
import {
|
||||
ExtendedError,
|
||||
ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS,
|
||||
ERROR_HTTP_UNEXPECTED_RESPONSE_STATE
|
||||
} from '../errors';
|
||||
|
||||
import { handleAxiosError } from './utils';
|
||||
import * as types from './types';
|
||||
|
||||
export function receiveError(error) {
|
||||
return {
|
||||
type: types.RECEIVE_ERROR,
|
||||
error
|
||||
};
|
||||
}
|
||||
|
||||
export function resetHello() {
|
||||
return {
|
||||
type: types.RESET_HELLO
|
||||
};
|
||||
}
|
||||
|
||||
export function receiveHello(hello) {
|
||||
const { success, username, displayName } = hello;
|
||||
|
||||
return {
|
||||
type: types.RECEIVE_HELLO,
|
||||
state: success === true,
|
||||
username,
|
||||
displayName,
|
||||
hello
|
||||
};
|
||||
}
|
||||
|
||||
export function executeHello() {
|
||||
return function(dispatch, getState) {
|
||||
dispatch(resetHello());
|
||||
|
||||
const { flow, query } = getState().common;
|
||||
|
||||
const r = withClientRequestState(newHelloRequest(flow, query));
|
||||
return axios.post('./identifier/_/hello', r, {
|
||||
headers: {
|
||||
'Kopano-Konnect-XSRF': '1'
|
||||
}
|
||||
}).then(response => {
|
||||
switch (response.status) {
|
||||
case 200:
|
||||
// success.
|
||||
return response.data;
|
||||
case 204:
|
||||
// not signed-in.
|
||||
return {
|
||||
success: false,
|
||||
state: response.headers['kopano-konnect-state']
|
||||
};
|
||||
default:
|
||||
// error.
|
||||
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response);
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.state !== r.state) {
|
||||
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATE, response);
|
||||
}
|
||||
|
||||
dispatch(receiveHello(response));
|
||||
return Promise.resolve(response);
|
||||
}).catch(error => {
|
||||
error = handleAxiosError(error);
|
||||
|
||||
dispatch(receiveError(error));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function retryHello() {
|
||||
return function(dispatch) {
|
||||
dispatch(receiveError(null));
|
||||
|
||||
return dispatch(executeHello());
|
||||
};
|
||||
}
|
||||
|
||||
export function requestLogoff() {
|
||||
return {
|
||||
type: types.REQUEST_LOGOFF
|
||||
};
|
||||
}
|
||||
|
||||
export function receiveLogoff(state) {
|
||||
return {
|
||||
type: types.RECEIVE_LOGOFF,
|
||||
state
|
||||
};
|
||||
}
|
||||
|
||||
export function executeLogoff() {
|
||||
return function(dispatch) {
|
||||
dispatch(resetHello());
|
||||
dispatch(requestLogoff());
|
||||
|
||||
const r = withClientRequestState({});
|
||||
return axios.post('./identifier/_/logoff', r, {
|
||||
headers: {
|
||||
'Kopano-Konnect-XSRF': '1'
|
||||
}
|
||||
}).then(response => {
|
||||
switch (response.status) {
|
||||
case 200:
|
||||
// success.
|
||||
return response.data;
|
||||
default:
|
||||
// error.
|
||||
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response);
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.state !== r.state) {
|
||||
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATE, response);
|
||||
}
|
||||
|
||||
dispatch(receiveLogoff(response.success === true));
|
||||
return Promise.resolve(response);
|
||||
}).catch(error => {
|
||||
error = handleAxiosError(error);
|
||||
|
||||
dispatch(receiveError(error));
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
import axios from 'axios';
|
||||
import queryString from 'query-string';
|
||||
|
||||
import { newHelloRequest } from '../models/hello';
|
||||
import { withClientRequestState } from '../utils';
|
||||
import {
|
||||
ExtendedError,
|
||||
ERROR_LOGIN_VALIDATE_MISSINGUSERNAME,
|
||||
ERROR_LOGIN_VALIDATE_MISSINGPASSWORD,
|
||||
ERROR_LOGIN_FAILED,
|
||||
ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS,
|
||||
ERROR_HTTP_UNEXPECTED_RESPONSE_STATE
|
||||
} from '../errors';
|
||||
|
||||
import * as types from './types';
|
||||
import { receiveHello } from './common';
|
||||
import { handleAxiosError } from './utils';
|
||||
|
||||
// Modes for logon.
|
||||
export const ModeLogonUsernameEmptyPasswordCookie = '0';
|
||||
export const ModeLogonUsernamePassword = '1';
|
||||
|
||||
export function updateInput(name, value) {
|
||||
return {
|
||||
type: types.UPDATE_INPUT,
|
||||
name,
|
||||
value
|
||||
};
|
||||
}
|
||||
|
||||
export function receiveValidateLogon(errors) {
|
||||
return {
|
||||
type: types.RECEIVE_VALIDATE_LOGON,
|
||||
errors
|
||||
};
|
||||
}
|
||||
|
||||
export function requestLogon(username, password) {
|
||||
return {
|
||||
type: types.REQUEST_LOGON,
|
||||
username,
|
||||
password
|
||||
};
|
||||
}
|
||||
|
||||
export function receiveLogon(logon) {
|
||||
const { success, errors } = logon;
|
||||
|
||||
return {
|
||||
type: types.RECEIVE_LOGON,
|
||||
success,
|
||||
errors
|
||||
};
|
||||
}
|
||||
|
||||
export function requestConsent(allow=false) {
|
||||
return {
|
||||
type: allow ? types.REQUEST_CONSENT_ALLOW : types.REQUEST_CONSENT_CANCEL
|
||||
};
|
||||
}
|
||||
|
||||
export function receiveConsent(logon) {
|
||||
const { success, errors } = logon;
|
||||
|
||||
return {
|
||||
type: types.RECEIVE_CONSENT,
|
||||
success,
|
||||
errors
|
||||
};
|
||||
}
|
||||
|
||||
export function executeLogon(username, password, mode=ModeLogonUsernamePassword) {
|
||||
return function(dispatch, getState) {
|
||||
dispatch(requestLogon(username, password));
|
||||
dispatch(receiveHello({
|
||||
username
|
||||
})); // Reset any hello state on logon.
|
||||
|
||||
const { flow, query } = getState().common;
|
||||
|
||||
// Prepare params based on mode.
|
||||
const params = [];
|
||||
switch (mode) {
|
||||
case ModeLogonUsernamePassword:
|
||||
// Username with password.
|
||||
params.push(username, password, mode);
|
||||
break;
|
||||
|
||||
case ModeLogonUsernameEmptyPasswordCookie:
|
||||
// Username with empty password - this only works when the user is already signed in.
|
||||
params.push(username, '', mode);
|
||||
break;
|
||||
}
|
||||
|
||||
const r = withClientRequestState({
|
||||
params: params,
|
||||
hello: newHelloRequest(flow, query)
|
||||
});
|
||||
return axios.post('./identifier/_/logon', r, {
|
||||
headers: {
|
||||
'Kopano-Konnect-XSRF': '1'
|
||||
}
|
||||
}).then(response => {
|
||||
switch (response.status) {
|
||||
case 200:
|
||||
// success.
|
||||
return response.data;
|
||||
case 204:
|
||||
// login failed.
|
||||
return {
|
||||
success: false,
|
||||
state: response.headers['kopano-konnect-state'],
|
||||
errors: {
|
||||
http: new Error(ERROR_LOGIN_FAILED)
|
||||
}
|
||||
};
|
||||
default:
|
||||
// error.
|
||||
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response);
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.state !== r.state) {
|
||||
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATE, response);
|
||||
}
|
||||
|
||||
let { hello } = response;
|
||||
if (!hello) {
|
||||
hello = {
|
||||
success: response.success,
|
||||
username
|
||||
};
|
||||
}
|
||||
dispatch(receiveHello(hello));
|
||||
dispatch(receiveLogon(response));
|
||||
return Promise.resolve(response);
|
||||
}).catch(error => {
|
||||
error = handleAxiosError(error);
|
||||
const errors = {
|
||||
http: error
|
||||
};
|
||||
|
||||
dispatch(receiveValidateLogon(errors));
|
||||
return {
|
||||
success: false,
|
||||
errors: errors
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function executeConsent(allow=false, scope='') {
|
||||
return function(dispatch, getState) {
|
||||
dispatch(requestConsent(allow));
|
||||
|
||||
const { query } = getState().common;
|
||||
|
||||
const r = withClientRequestState({
|
||||
allow,
|
||||
scope,
|
||||
client_id: query.client_id || '', // eslint-disable-line camelcase
|
||||
redirect_uri: query.redirect_uri || '', // eslint-disable-line camelcase
|
||||
ref: query.state || '',
|
||||
flow_nonce: query.nonce || '' // eslint-disable-line camelcase
|
||||
});
|
||||
return axios.post('./identifier/_/consent', r, {
|
||||
headers: {
|
||||
'Kopano-Konnect-XSRF': '1'
|
||||
}
|
||||
}).then(response => {
|
||||
switch (response.status) {
|
||||
case 200:
|
||||
// success.
|
||||
return response.data;
|
||||
case 204:
|
||||
// cancel reply.
|
||||
return {
|
||||
success: true,
|
||||
state: response.headers['kopano-konnect-state']
|
||||
};
|
||||
default:
|
||||
// error.
|
||||
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response);
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.state !== r.state) {
|
||||
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATE, response);
|
||||
}
|
||||
|
||||
dispatch(receiveConsent(response));
|
||||
return Promise.resolve(response);
|
||||
}).catch(error => {
|
||||
error = handleAxiosError(error);
|
||||
const errors = {
|
||||
http: error
|
||||
};
|
||||
|
||||
dispatch(receiveValidateLogon(errors));
|
||||
return {
|
||||
success: false,
|
||||
errors: errors
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function validateUsernamePassword(username, password, isSignedIn) {
|
||||
return function(dispatch) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const errors = {};
|
||||
|
||||
if (!username) {
|
||||
errors.username = new Error(ERROR_LOGIN_VALIDATE_MISSINGUSERNAME);
|
||||
}
|
||||
if (!password && !isSignedIn) {
|
||||
errors.password = new Error(ERROR_LOGIN_VALIDATE_MISSINGPASSWORD);
|
||||
}
|
||||
|
||||
dispatch(receiveValidateLogon(errors));
|
||||
if (Object.keys(errors).length === 0) {
|
||||
resolve(errors);
|
||||
} else {
|
||||
reject(errors);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function executeLogonIfFormValid(username, password, isSignedIn) {
|
||||
return (dispatch) => {
|
||||
return dispatch(
|
||||
validateUsernamePassword(username, password, isSignedIn)
|
||||
).then(() => {
|
||||
const mode = isSignedIn ? ModeLogonUsernameEmptyPasswordCookie : ModeLogonUsernamePassword;
|
||||
return dispatch(executeLogon(username, password, mode));
|
||||
}).catch((errors) => {
|
||||
return {
|
||||
success: false,
|
||||
errors: errors
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function advanceLogonFlow(success, history, done=false, extraQuery={}) {
|
||||
return (dispatch, getState) => {
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { flow, query, hello } = getState().common;
|
||||
const q = Object.assign({}, query, extraQuery);
|
||||
|
||||
switch (flow) {
|
||||
case 'oauth':
|
||||
case 'consent':
|
||||
case 'oidc':
|
||||
if (hello.details.flow !== flow) {
|
||||
// Ignore requested flow if hello flow does not match.
|
||||
break;
|
||||
}
|
||||
|
||||
if (!done && hello.details.next === 'consent') {
|
||||
history.replace(`/consent${history.location.search}${history.location.hash}`);
|
||||
return;
|
||||
}
|
||||
if (hello.details.continue_uri) {
|
||||
q.prompt = 'none';
|
||||
window.location.replace(hello.details.continue_uri + '?' + queryString.stringify(q));
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// Legacy stupid modes.
|
||||
if (q.continue && q.continue.indexOf(document.location.origin) === 0) {
|
||||
window.location.replace(q.continue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Default action.
|
||||
let target = '/welcome';
|
||||
if (history.action === 'REPLACE') {
|
||||
target = target + history.location.search + history.location.hash;
|
||||
}
|
||||
|
||||
dispatch(receiveValidateLogon({})); // XXX(longsleep): hack to reset loading and errors.
|
||||
history.push(target);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
export const RECEIVE_ERROR = 'RECEIVE_ERROR';
|
||||
|
||||
export const RESET_HELLO = 'RESET_HELLO';
|
||||
export const EXECUTE_HELLO = 'EXECUTE_HELLO';
|
||||
export const RECEIVE_HELLO = 'RECEIVE_HELLO';
|
||||
|
||||
export const RECEIVE_VALIDATE_LOGON = 'RECEIVE_VALIDATE_LOGON';
|
||||
export const REQUEST_LOGON = 'REQUEST_LOGON';
|
||||
export const EXECUTE_LOGON = 'EXECUTE_LOGON';
|
||||
export const RECEIVE_LOGON = 'RECEIVE_LOGON';
|
||||
export const UPDATE_INPUT = 'UPDATE_INPUT';
|
||||
|
||||
export const REQUEST_CONSENT_ALLOW = 'REQUEST_CONSENT_ALLOW';
|
||||
export const REQUEST_CONSENT_CANCEL = 'REQUEST_CONSENT_CANCEL';
|
||||
export const EXECUTE_CONSENT = 'EXECUTE_CONSENT';
|
||||
export const RECEIVE_CONSENT = 'RECEIVE_CONSENT';
|
||||
|
||||
export const REQUEST_LOGOFF = 'REQUEST_LOGOFF';
|
||||
export const EXECUTE_LOGOFF = 'EXECUTE_LOGOFF';
|
||||
export const RECEIVE_LOGOFF = 'RECEIVE_LOGOFF';
|
||||
|
||||
export const SERVICE_WORKER_NEW_CONTENT = 'SERVICE_WORKER_NEW_CONTENT';
|
||||
export const SERVICE_WORKER_READY = 'SERVICE_WORKER_READY';
|
||||
export const SERVICE_WORKER_ERROR = 'SERVICE_WORKER_ERROR';
|
||||
export const SERVICE_WORKER_OFFLINE = 'SERVICE_WORKER_OFFLINE';
|
||||
@@ -0,0 +1,18 @@
|
||||
import {
|
||||
ExtendedError,
|
||||
ERROR_HTTP_NETWORK_ERROR,
|
||||
ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS
|
||||
} from '../errors';
|
||||
|
||||
export function handleAxiosError(error) {
|
||||
if (error.request) {
|
||||
// Axios errors.
|
||||
if (error.response) {
|
||||
error = new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, error.response);
|
||||
} else {
|
||||
error = new ExtendedError(ERROR_HTTP_NETWORK_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/* additional css on top of kpop */
|
||||
html {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.oc-login-bg {
|
||||
background-image: url(./images/background.jpg);
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#loader {
|
||||
/* NOTE(longsleep): White here needed because of the background image */
|
||||
color: white;
|
||||
text-shadow: #000 0 0 1px;
|
||||
}
|
||||
|
||||
.oc-logo {
|
||||
position: absolute;
|
||||
top: -130px;
|
||||
left: 50%;
|
||||
height: 80px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.oc-progress {
|
||||
/* Needs to be important to overwrite material-ui */
|
||||
background-color: rgba(78, 133, 200, 0.8) !important;
|
||||
height: 4px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.oc-progress > div {
|
||||
/* Needs to be important to overwrite material-ui */
|
||||
background-color: #4a76ac !important;
|
||||
}
|
||||
|
||||
.oc-input {
|
||||
background-color: #042047;
|
||||
border: 1px solid rgba(78, 133, 200, 0.8);
|
||||
border-radius: 3px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
height: 40px;
|
||||
width: 300px;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.oc-label {
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.oc-input.error {
|
||||
outline: none;
|
||||
border: 1px solid #fe4600;
|
||||
}
|
||||
|
||||
.MuiTypography-colorError {
|
||||
color: #fe4600 !important;
|
||||
}
|
||||
|
||||
.oc-input:focus {
|
||||
outline: none;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
.oc-input::placeholder {
|
||||
color: rgba(78, 133, 200, 0.8);
|
||||
}
|
||||
|
||||
.oc-input + .oc-input {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.MuiTouchRipple-root {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.oc-button {
|
||||
/* Needs to be important to overwrite material-ui */
|
||||
font-size: 1.0625rem !important;
|
||||
}
|
||||
|
||||
.oc-button-primary {
|
||||
/* Needs to be important to overwrite material-ui */
|
||||
background-color: #4a76ac !important;
|
||||
border: 1px solid transparent !important;
|
||||
}
|
||||
|
||||
.oc-button-primary:hover,
|
||||
.oc-button-primary:focus {
|
||||
/* Needs to be important to overwrite material-ui */
|
||||
background-color: #4a76ac !important;
|
||||
border: 1px solid white !important;
|
||||
}
|
||||
|
||||
.oc-checkbox-dark svg {
|
||||
/* Needs to be important to overwrite material-ui */
|
||||
fill: white !important;
|
||||
}
|
||||
|
||||
.oc-footer-message {
|
||||
color: white;
|
||||
padding: 10px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.oc-logo {
|
||||
height: 60px;
|
||||
top: -90px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helpers */
|
||||
.oc-mt-l {
|
||||
margin-top: 30px !important;
|
||||
}
|
||||
|
||||
.oc-mb-m {
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
.oc-light {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.oc-login-form div:not(:last-of-type) {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Special SR classes
|
||||
* Used to hide an element visually, but keeping it accessible for accessibility tools.
|
||||
*/
|
||||
.oc-invisible-sr {
|
||||
border: 0 !important;
|
||||
clip: rect(1px, 1px, 1px, 1px) !important;
|
||||
height: 1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
/* Need to make sure we override any existing styles. */
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
white-space: nowrap;
|
||||
width: 1px !important;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Loadable from 'react-loadable';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { MuiThemeProvider } from '@material-ui/core/styles';
|
||||
|
||||
import { defaultTheme as theme } from 'kpop/es/theme';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import Loading from 'kpop/es/Loading';
|
||||
import { unregister } from 'kpop/es/serviceWorker';
|
||||
|
||||
import store from './store';
|
||||
import translations from './locales';
|
||||
|
||||
// NOTE(longsleep): Load async with loader, this enables code splitting via Webpack.
|
||||
const LoadableApp = Loadable({
|
||||
loader: () => import(/* webpackChunkName: "identifier-main" */ './Main'),
|
||||
loading: Loading,
|
||||
timeout: 20000
|
||||
});
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<IntlProvider messages={translations} locale="en" defaultLocale="en">
|
||||
<LoadableApp />
|
||||
</IntlProvider>
|
||||
</MuiThemeProvider>
|
||||
</Provider>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
||||
unregister();
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const ClientDisplayName = ({ client, ...rest }) => (
|
||||
<span {...rest}>{client.display_name ? client.display_name : client.id}</span>
|
||||
);
|
||||
|
||||
ClientDisplayName.propTypes = {
|
||||
client: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default ClientDisplayName;
|
||||
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import LinearProgress from '@material-ui/core/LinearProgress';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import renderIf from 'render-if';
|
||||
|
||||
import { retryHello } from '../actions/common';
|
||||
import { ErrorMessage } from '../errors';
|
||||
|
||||
function Loading({ error, dispatch }) {
|
||||
const retry = (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(retryHello());
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid item align="center">
|
||||
{renderIf(error === null)(() => (
|
||||
<LinearProgress className="oc-progress" />
|
||||
))}
|
||||
{renderIf(error !== null)(() => (
|
||||
<div>
|
||||
<Typography className="oc-light" variant="h5" gutterBottom align="center">
|
||||
<FormattedMessage id="konnect.loading.error.headline" defaultMessage="Failed to connect to server" />
|
||||
</Typography>
|
||||
<Typography align="center" color="error">
|
||||
<ErrorMessage error={error} />
|
||||
</Typography>
|
||||
<Button
|
||||
autoFocus
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className="oc-button-primary oc-mt-l"
|
||||
onClick={(event) => retry(event)}
|
||||
>
|
||||
<FormattedMessage id="konnect.login.retryButton.label" defaultMessage="Retry" />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
Loading.propTypes = {
|
||||
error: PropTypes.object,
|
||||
dispatch: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { error } = state.common;
|
||||
|
||||
return {
|
||||
error
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(Loading);
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Route } from 'react-router-dom';
|
||||
|
||||
import RedirectWithQuery from './RedirectWithQuery';
|
||||
|
||||
const PrivateRoute = ({ component: Target, hello, ...rest }) => (
|
||||
<Route {...rest} render={props => (
|
||||
hello ? (
|
||||
<Target {...props}/>
|
||||
) : (
|
||||
<RedirectWithQuery target='/identifier' />
|
||||
)
|
||||
)}/>
|
||||
);
|
||||
|
||||
PrivateRoute.propTypes = {
|
||||
component: PropTypes.func.isRequired,
|
||||
hello: PropTypes.object
|
||||
};
|
||||
|
||||
export default PrivateRoute;
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
|
||||
const RedirectWithQuery = ({target, location, ...rest}) => {
|
||||
const to = {
|
||||
pathname: target,
|
||||
search: location.search,
|
||||
hash: location.hash
|
||||
};
|
||||
|
||||
return (
|
||||
<Redirect to={to} {...rest}></Redirect>
|
||||
);
|
||||
};
|
||||
|
||||
RedirectWithQuery.propTypes = {
|
||||
target: PropTypes.string.isRequired,
|
||||
location: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default withRouter(RedirectWithQuery);
|
||||
@@ -0,0 +1,95 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
|
||||
import Loading from './Loading';
|
||||
|
||||
const styles = theme => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
flex: 1
|
||||
},
|
||||
content: {
|
||||
position: 'relative',
|
||||
width: '100%'
|
||||
},
|
||||
actions: {
|
||||
marginTop: -40,
|
||||
justifyContent: 'flex-start',
|
||||
paddingLeft: theme.spacing(3),
|
||||
paddingRight: theme.spacing(3)
|
||||
},
|
||||
wrapper: {
|
||||
width: '100%',
|
||||
maxWidth: 300,
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
alignItems: 'center'
|
||||
}
|
||||
});
|
||||
|
||||
const footerProductName = name => <strong>{name}</strong>;
|
||||
|
||||
const ResponsiveScreen = (props) => {
|
||||
const {
|
||||
classes,
|
||||
withoutLogo,
|
||||
withoutPadding,
|
||||
loading,
|
||||
children,
|
||||
className,
|
||||
DialogProps,
|
||||
PaperProps,
|
||||
...other
|
||||
} = props;
|
||||
|
||||
const logo = withoutLogo ? null :
|
||||
<img src={process.env.PUBLIC_URL + '/static/logo.svg'} className="oc-logo" alt="ownCloud Logo"/>;
|
||||
|
||||
const content = loading ? <Loading/> : (withoutPadding ? children : <DialogContent>{children}</DialogContent>);
|
||||
|
||||
return (
|
||||
<Grid container justify="center" alignItems="center" direction="column" spacing={0}
|
||||
className={classNames(classes.root, className)} {...other}>
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.content}>
|
||||
{logo}
|
||||
{content}
|
||||
</div>
|
||||
</div>
|
||||
<footer className="oc-footer-message">
|
||||
<FormattedMessage
|
||||
id="konnect.footer.slogan"
|
||||
defaultMessage="<name>ownCloud</name> - a safe home for all your data"
|
||||
values={{
|
||||
name: chunks => footerProductName(chunks)
|
||||
}}
|
||||
/>
|
||||
</footer>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
ResponsiveScreen.defaultProps = {
|
||||
withoutLogo: false,
|
||||
withoutPadding: false,
|
||||
loading: false
|
||||
};
|
||||
|
||||
ResponsiveScreen.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
withoutLogo: PropTypes.bool,
|
||||
withoutPadding: PropTypes.bool,
|
||||
loading: PropTypes.bool,
|
||||
children: PropTypes.node.isRequired,
|
||||
className: PropTypes.string,
|
||||
PaperProps: PropTypes.object,
|
||||
DialogProps: PropTypes.object
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ResponsiveScreen);
|
||||
@@ -0,0 +1,102 @@
|
||||
import React from 'react';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import PropTypes from 'prop-types';
|
||||
import Checkbox from '@material-ui/core/Checkbox';
|
||||
|
||||
import { injectIntl, useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
||||
|
||||
const styles = () => ({
|
||||
row: {
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0
|
||||
}
|
||||
});
|
||||
|
||||
const scopeIDTranslations = defineMessages({
|
||||
'scope_alias_basic': {
|
||||
id: 'konnect.scopeDescription.aliasBasic',
|
||||
defaultMessage: 'Access your basic account information'
|
||||
},
|
||||
'scope_offline_access': {
|
||||
id: 'konnect.scopeDescription.offlineAccess',
|
||||
defaultMessage: 'Keep the allowed access persistently and forever'
|
||||
}
|
||||
});
|
||||
|
||||
const ScopesList = ({scopes, meta, classes, ...rest}) => {
|
||||
const { mapping, definitions } = meta;
|
||||
const intl = useIntl()
|
||||
|
||||
const rows = [];
|
||||
const known = {};
|
||||
|
||||
// TODO(longsleep): Sort scopes according to priority.
|
||||
for (let scope in scopes) {
|
||||
if (!scopes[scope]) {
|
||||
continue;
|
||||
}
|
||||
let id = mapping[scope];
|
||||
if (id) {
|
||||
if (known[id]) {
|
||||
continue;
|
||||
}
|
||||
known[id] = true;
|
||||
} else {
|
||||
id = scope;
|
||||
}
|
||||
let definition = definitions[id];
|
||||
let label ;
|
||||
if (definition) {
|
||||
if (definition.id) {
|
||||
const translation = scopeIDTranslations[definition.id];
|
||||
if (translation) {
|
||||
label = intl.formatMessage(translation);
|
||||
}
|
||||
}
|
||||
if (!label) {
|
||||
label = definition.description;
|
||||
}
|
||||
}
|
||||
if (!label) {
|
||||
label = <FormattedMessage
|
||||
id="konnect.scopeDescription.scope"
|
||||
defaultMessage="Scope: {scope}"
|
||||
values={{scope}}
|
||||
/>;
|
||||
}
|
||||
|
||||
rows.push(
|
||||
<ListItem
|
||||
disableGutters
|
||||
dense
|
||||
key={id}
|
||||
className={classes.row}
|
||||
><Checkbox
|
||||
checked
|
||||
disableRipple
|
||||
disabled
|
||||
className="oc-checkbox-dark"
|
||||
/>
|
||||
<ListItemText primary={label} className="oc-light" />
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<List {...rest}>
|
||||
{rows}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
||||
ScopesList.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
scopes: PropTypes.object.isRequired,
|
||||
meta: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default withStyles(styles)(injectIntl(ScopesList));
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {useIntl} from 'react-intl';
|
||||
|
||||
const TextInput = (props) => {
|
||||
const intl = useIntl();
|
||||
const label = props.label;
|
||||
const extraClassName = props.extraClassName;
|
||||
|
||||
delete props.label;
|
||||
delete props.extraClassName;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label className="oc-label"
|
||||
htmlFor={props.id}>{intl.formatMessage(label)}</label>
|
||||
<input className={`oc-input ${extraClassName ? extraClassName : ''}`} {...props}
|
||||
placeholder={props.placeholder ? intl.formatMessage(props.placeholder) : null}/>
|
||||
</div>);
|
||||
};
|
||||
|
||||
TextInput.propTypes = {
|
||||
placeholder: PropTypes.object,
|
||||
label: PropTypes.object,
|
||||
id: PropTypes.string,
|
||||
extraClassName: props.string,
|
||||
}
|
||||
|
||||
export default TextInput;
|
||||
@@ -0,0 +1,125 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import renderIf from 'render-if';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
|
||||
import ResponsiveScreen from '../../components/ResponsiveScreen';
|
||||
import { executeHello, executeLogoff } from '../../actions/common';
|
||||
|
||||
const styles = theme => ({
|
||||
subHeader: {
|
||||
marginBottom: theme.spacing(5)
|
||||
},
|
||||
wrapper: {
|
||||
marginTop: theme.spacing(5),
|
||||
position: 'relative',
|
||||
display: 'inline-block'
|
||||
}
|
||||
});
|
||||
|
||||
class Goodbyescreen extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
this.props.dispatch(executeHello());
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, hello } = this.props;
|
||||
|
||||
const loading = hello === null;
|
||||
return (
|
||||
<ResponsiveScreen loading={loading}>
|
||||
{renderIf(hello !== null && !hello.state)(() => (
|
||||
<div>
|
||||
<Typography variant="h5" component="h3">
|
||||
<FormattedMessage id="konnect.goodbye.headline" defaultMessage="Goodbye"></FormattedMessage>
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" className={classes.subHeader}>
|
||||
<FormattedMessage id="konnect.goodbye.subHeader"
|
||||
defaultMessage="you have been signed out from your Kopano account">
|
||||
</FormattedMessage>
|
||||
</Typography>
|
||||
<Typography gutterBottom>
|
||||
<FormattedMessage id="konnect.goodbye.message.close"
|
||||
defaultMessage="You can close this window now.">
|
||||
</FormattedMessage>
|
||||
</Typography>
|
||||
</div>
|
||||
))}
|
||||
{renderIf(hello !== null && hello.state === true)(() => (
|
||||
<div>
|
||||
<Typography variant="h5" component="h3">
|
||||
<FormattedMessage
|
||||
id="konnect.goodbye.confirm.headline"
|
||||
defaultMessage="Hello {displayName}"
|
||||
values={{displayName: hello.displayName}}>
|
||||
</FormattedMessage>
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" className={classes.subHeader}>
|
||||
<FormattedMessage id="konnect.goodbye.confirm.subHeader"
|
||||
defaultMessage="please confirm sign out">
|
||||
</FormattedMessage>
|
||||
</Typography>
|
||||
|
||||
<Typography gutterBottom>
|
||||
<FormattedMessage id="konnect.goodbye.message.confirm"
|
||||
defaultMessage="Press the button below, to sign out from your Kopano account now.">
|
||||
</FormattedMessage>
|
||||
</Typography>
|
||||
|
||||
<DialogActions>
|
||||
<div className={classes.wrapper}>
|
||||
<Button
|
||||
color="secondary"
|
||||
className={classes.button}
|
||||
onClick={(event) => this.logoff(event)}
|
||||
>
|
||||
<FormattedMessage id="konnect.goodbye.signoutButton.label"
|
||||
defaultMessage="Sign out"></FormattedMessage>
|
||||
</Button>
|
||||
</div>
|
||||
</DialogActions>
|
||||
</div>
|
||||
))}
|
||||
</ResponsiveScreen>
|
||||
);
|
||||
}
|
||||
|
||||
logoff(event) {
|
||||
event.preventDefault();
|
||||
|
||||
this.props.dispatch(executeLogoff()).then((response) => {
|
||||
const { history } = this.props;
|
||||
|
||||
if (response.success) {
|
||||
this.props.dispatch(executeHello());
|
||||
history.push('/goodbye');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Goodbyescreen.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
hello: PropTypes.object,
|
||||
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { hello } = state.common;
|
||||
|
||||
return {
|
||||
hello
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(withStyles(styles)(Goodbyescreen));
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './Goodbyescreen';
|
||||
@@ -0,0 +1,144 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||
import Avatar from '@material-ui/core/Avatar';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
|
||||
import { executeLogonIfFormValid, advanceLogonFlow } from '../../actions/login';
|
||||
import { ErrorMessage } from '../../errors';
|
||||
|
||||
const styles = theme => ({
|
||||
subHeader: {
|
||||
marginBottom: theme.spacing(2)
|
||||
},
|
||||
message: {
|
||||
marginTop: theme.spacing(2)
|
||||
},
|
||||
accountList: {
|
||||
marginLeft: theme.spacing(-3),
|
||||
marginRight: theme.spacing(-3)
|
||||
},
|
||||
accountListItem: {
|
||||
paddingLeft: theme.spacing(3),
|
||||
paddingRight: theme.spacing(3)
|
||||
}
|
||||
});
|
||||
|
||||
function Chooseaccount({ loading, errors, classes, hello, history, dispatch }) {
|
||||
useEffect(() => {
|
||||
if ((!hello || !hello.state) && history.action !== 'PUSH') {
|
||||
history.replace(`/identifier${history.location.search}${history.location.hash}`);
|
||||
}
|
||||
});
|
||||
|
||||
let errorMessage = null;
|
||||
|
||||
if (errors.http) {
|
||||
errorMessage = <Typography color="error" className={classes.message}>
|
||||
<ErrorMessage error={errors.http}></ErrorMessage>
|
||||
</Typography>;
|
||||
}
|
||||
|
||||
let username = '';
|
||||
|
||||
if (hello && hello.state) {
|
||||
username = hello.username;
|
||||
}
|
||||
|
||||
const logon = (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(executeLogonIfFormValid(hello.username, '', true)).then((response) => {
|
||||
if (response.success) {
|
||||
dispatch(advanceLogonFlow(response.success, history));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const logoff = (event) => {
|
||||
event.preventDefault();
|
||||
history.push(`/identifier${history.location.search}${history.location.hash}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography variant="h5" component="h3" className="oc-light">
|
||||
<FormattedMessage id="konnect.chooseaccount.headline" defaultMessage="Choose an account"></FormattedMessage>
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" className={classes.subHeader + " oc-light"}>
|
||||
<FormattedMessage id="konnect.chooseaccount.subHeader" defaultMessage="to sign in to Kopano">
|
||||
</FormattedMessage>
|
||||
</Typography>
|
||||
|
||||
<form action="" onSubmit={(event) => logon(event)}>
|
||||
<List disablePadding className={classes.accountList}>
|
||||
<ListItem
|
||||
button
|
||||
disableGutters
|
||||
className={classes.accountListItem}
|
||||
disabled={!!loading}
|
||||
onClick={(event) => logon(event)}
|
||||
><ListItemAvatar><Avatar>{username.slice(0, 1)}</Avatar></ListItemAvatar>
|
||||
<ListItemText className="oc-light" primary={username} />
|
||||
</ListItem>
|
||||
<ListItem
|
||||
button
|
||||
disableGutters
|
||||
className={classes.accountListItem}
|
||||
disabled={!!loading}
|
||||
onClick={(event) => logoff(event)}
|
||||
>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<FormattedMessage id="konnect.chooseaccount.useOther.persona.label" defaultMessage="?">
|
||||
</FormattedMessage>
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
className="oc-light"
|
||||
primary={
|
||||
<FormattedMessage
|
||||
id="konnect.chooseaccount.useOther.label"
|
||||
defaultMessage="Use another account">
|
||||
</FormattedMessage>
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
|
||||
{errorMessage}
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Chooseaccount.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
loading: PropTypes.string.isRequired,
|
||||
errors: PropTypes.object.isRequired,
|
||||
hello: PropTypes.object,
|
||||
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { loading, errors } = state.login;
|
||||
const { hello } = state.common;
|
||||
|
||||
return {
|
||||
loading,
|
||||
errors,
|
||||
hello
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(withStyles(styles)(Chooseaccount));
|
||||
@@ -0,0 +1,187 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import renderIf from 'render-if';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import CircularProgress from '@material-ui/core/CircularProgress';
|
||||
import green from '@material-ui/core/colors/green';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
|
||||
import { executeConsent, advanceLogonFlow, receiveValidateLogon } from '../../actions/login';
|
||||
import { ErrorMessage } from '../../errors';
|
||||
import { REQUEST_CONSENT_ALLOW } from '../../actions/types';
|
||||
import ClientDisplayName from '../../components/ClientDisplayName';
|
||||
import ScopesList from '../../components/ScopesList';
|
||||
|
||||
const styles = theme => ({
|
||||
buttonProgress: {
|
||||
color: green[500],
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
marginTop: -12,
|
||||
marginLeft: -12
|
||||
},
|
||||
scopesList: {
|
||||
marginBottom: theme.spacing(2)
|
||||
},
|
||||
wrapper: {
|
||||
marginTop: theme.spacing(2),
|
||||
position: 'relative',
|
||||
display: 'inline-block'
|
||||
},
|
||||
message: {
|
||||
marginTop: theme.spacing(2),
|
||||
marginBottom: theme.spacing(2)
|
||||
}
|
||||
});
|
||||
|
||||
class Consent extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
const { dispatch, hello, history, client } = this.props;
|
||||
if ((!hello || !hello.state || !client) && history.action !== 'PUSH') {
|
||||
history.replace(`/identifier${history.location.search}${history.location.hash}`);
|
||||
}
|
||||
|
||||
dispatch(receiveValidateLogon({})); // XXX(longsleep): hack to reset loading and errors.
|
||||
}
|
||||
|
||||
action = (allow=false, scopes={}) => (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (allow === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert all scopes which are true to a scope value.
|
||||
const scope = Object.keys(scopes).filter(scope => {
|
||||
return !!scopes[scope];
|
||||
}).join(' ');
|
||||
|
||||
const { dispatch, history } = this.props;
|
||||
dispatch(executeConsent(allow, scope)).then((response) => {
|
||||
if (response.success) {
|
||||
dispatch(advanceLogonFlow(response.success, history, true, {konnect: response.state}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, loading, hello, errors, client } = this.props;
|
||||
|
||||
const scopes = hello.details.scopes || {};
|
||||
const meta = hello.details.meta || {};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography variant="h5" component="h3" className="oc-light">
|
||||
<FormattedMessage
|
||||
id="konnect.consent.headline"
|
||||
defaultMessage="Hi {displayName}"
|
||||
values={{displayName: hello.displayName}}
|
||||
/>
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" className="oc-light oc-mb-m">
|
||||
{hello.username}
|
||||
</Typography>
|
||||
|
||||
<Typography variant="subtitle1" gutterBottom className="oc-light">
|
||||
<FormattedMessage
|
||||
id="konnect.consent.message"
|
||||
defaultMessage="{clientDisplayName} wants to"
|
||||
values={{clientDisplayName:
|
||||
<Tooltip
|
||||
placement="bottom"
|
||||
title={<FormattedMessage
|
||||
id="konnect.consent.tooltip.client"
|
||||
defaultMessage='Clicking "Allow" will redirect you to: {redirectURI}'
|
||||
values={{
|
||||
redirectURI: client.redirect_uri
|
||||
}}
|
||||
></FormattedMessage>}
|
||||
>
|
||||
<em><ClientDisplayName client={client}/></em>
|
||||
</Tooltip>
|
||||
}}
|
||||
></FormattedMessage>
|
||||
</Typography>
|
||||
<ScopesList dense disablePadding className={classes.scopesList} scopes={scopes} meta={meta.scopes}></ScopesList>
|
||||
|
||||
<Typography className="oc-light">
|
||||
<FormattedMessage
|
||||
id="konnect.consent.consequence"
|
||||
defaultMessage="By clicking Allow, you allow this app to use your information.">
|
||||
</FormattedMessage>
|
||||
</Typography>
|
||||
|
||||
<form action="" onSubmit={this.action(undefined, scopes)}>
|
||||
<DialogActions>
|
||||
<div className={classes.wrapper}>
|
||||
<Button
|
||||
color="secondary"
|
||||
className={classes.button}
|
||||
disabled={!!loading}
|
||||
onClick={this.action(false, scopes)}
|
||||
>
|
||||
<FormattedMessage id="konnect.consent.cancelButton.label" defaultMessage="Cancel"></FormattedMessage>
|
||||
</Button>
|
||||
{(loading && loading !== REQUEST_CONSENT_ALLOW) &&
|
||||
<CircularProgress size={24} className={classes.buttonProgress} />}
|
||||
</div>
|
||||
<div className={classes.wrapper}>
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className="oc-button-primary"
|
||||
disabled={!!loading}
|
||||
onClick={this.action(true, scopes)}
|
||||
>
|
||||
<FormattedMessage id="konnect.consent.allowButton.label" defaultMessage="Allow"></FormattedMessage>
|
||||
</Button>
|
||||
{loading === REQUEST_CONSENT_ALLOW && <CircularProgress size={24} className={classes.buttonProgress} />}
|
||||
</div>
|
||||
</DialogActions>
|
||||
|
||||
{renderIf(errors.http)(() => (
|
||||
<Typography variant="subtitle2" color="error" className={classes.message}>
|
||||
<ErrorMessage error={errors.http}></ErrorMessage>
|
||||
</Typography>
|
||||
))}
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Consent.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
loading: PropTypes.string.isRequired,
|
||||
errors: PropTypes.object.isRequired,
|
||||
hello: PropTypes.object,
|
||||
client: PropTypes.object.isRequired,
|
||||
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { hello } = state.common;
|
||||
const { loading, errors } = state.login;
|
||||
|
||||
return {
|
||||
loading: loading,
|
||||
errors,
|
||||
hello,
|
||||
client: hello.details.client || {}
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(withStyles(styles)(Consent));
|
||||
@@ -0,0 +1,181 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import CircularProgress from '@material-ui/core/CircularProgress';
|
||||
import green from '@material-ui/core/colors/green';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Link from '@material-ui/core/Link';
|
||||
|
||||
import TextInput from '../../components/TextInput'
|
||||
|
||||
import { updateInput, executeLogonIfFormValid, advanceLogonFlow } from '../../actions/login';
|
||||
import { ErrorMessage } from '../../errors';
|
||||
|
||||
const styles = theme => ({
|
||||
buttonProgress: {
|
||||
color: green[500],
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
marginTop: -12,
|
||||
marginLeft: -12
|
||||
},
|
||||
subHeader: {
|
||||
marginBottom: theme.spacing(3)
|
||||
},
|
||||
wrapper: {
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
textAlign: 'center'
|
||||
},
|
||||
message: {
|
||||
marginTop: 5,
|
||||
marginBottom: 5
|
||||
}
|
||||
});
|
||||
|
||||
class Login extends React.PureComponent {
|
||||
state = {};
|
||||
|
||||
componentDidMount() {
|
||||
const { hello, query, dispatch, history } = this.props;
|
||||
if (hello && hello.state && history.action !== 'PUSH') {
|
||||
if (!query.prompt || query.prompt.indexOf('select_account') == -1) {
|
||||
dispatch(advanceLogonFlow(true, history));
|
||||
return;
|
||||
}
|
||||
|
||||
history.replace(`/chooseaccount${history.location.search}${history.location.hash}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { loading, errors, classes, username, passwordResetLink } = this.props;
|
||||
const loginFailed = errors.http;
|
||||
const hasError = errors.http || errors.username || errors.password;
|
||||
const errorMessage = errors.http
|
||||
? <ErrorMessage error={errors.http}></ErrorMessage>
|
||||
: (errors.username
|
||||
? <ErrorMessage error={errors.username}></ErrorMessage>
|
||||
: <ErrorMessage error={errors.password}></ErrorMessage>);
|
||||
const extraPropsUsername = {
|
||||
"aria-invalid" : (errors.username || errors.http) ? 'true' : 'false'
|
||||
};
|
||||
const extraPropsPassword = {
|
||||
"aria-invalid" : (errors.password || errors.http) ? 'true' : 'false',
|
||||
};
|
||||
|
||||
if(errors.username || errors.http){
|
||||
extraPropsUsername['extraClassName'] = 'error';
|
||||
extraPropsUsername['aria-describedby'] = 'oc-login-error-message';
|
||||
}
|
||||
|
||||
if(errors.password || errors.http){
|
||||
extraPropsPassword['extraClassName'] = 'error';
|
||||
extraPropsPassword['aria-describedby'] = 'oc-login-error-message';
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* eslint-disable-next-line react-intl-format/missing-formatted-message */}
|
||||
<h1 className="oc-invisible-sr"> Login </h1>
|
||||
<form action="" className="oc-login-form" onSubmit={(event) => this.logon(event)}>
|
||||
<TextInput
|
||||
autoFocus
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={username}
|
||||
onChange={this.handleChange('username')}
|
||||
autoComplete="kopano-account username"
|
||||
placeholder={({id: "konnect.login.usernameField.label", defaultMessage: "Username"})}
|
||||
label={({id: "konnect.login.usernameField.label", defaultMessage: "Username"})}
|
||||
id="oc-login-username"
|
||||
{...extraPropsUsername}
|
||||
/>
|
||||
<TextInput
|
||||
type="password"
|
||||
margin="normal"
|
||||
onChange={this.handleChange('password')}
|
||||
autoComplete="kopano-account current-password"
|
||||
placeholder={({id: "konnect.login.usernameField.label", defaultMessage: "Password"})}
|
||||
label={({id: "konnect.login.usernameField.label", defaultMessage: "Password"})}
|
||||
id="oc-login-password"
|
||||
{...extraPropsPassword}
|
||||
/>
|
||||
{hasError && <Typography id="oc-login-error-message" variant="subtitle2" component="span" color="error"
|
||||
className={classes.message}>{errorMessage}</Typography>}
|
||||
<div className={classes.wrapper}>
|
||||
{loginFailed && passwordResetLink && <Link id="oc-login-password-reset" href={passwordResetLink} variant="subtitle2">{"Reset password?"}</Link>}
|
||||
<br />
|
||||
<Button
|
||||
type="submit"
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className="oc-button-primary oc-mt-l"
|
||||
disabled={!!loading}
|
||||
onClick={(event) => this.logon(event)}
|
||||
>
|
||||
<FormattedMessage id="konnect.login.nextButton.label" defaultMessage="Log in"></FormattedMessage>
|
||||
</Button>
|
||||
{loading && <CircularProgress size={24} className={classes.buttonProgress}/>}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
handleChange(name) {
|
||||
return event => {
|
||||
this.props.dispatch(updateInput(name, event.target.value));
|
||||
};
|
||||
}
|
||||
|
||||
logon(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const { username, password, dispatch, history } = this.props;
|
||||
dispatch(executeLogonIfFormValid(username, password, false)).then((response) => {
|
||||
if (response.success) {
|
||||
dispatch(advanceLogonFlow(response.success, history));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Login.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
loading: PropTypes.string.isRequired,
|
||||
username: PropTypes.string.isRequired,
|
||||
password: PropTypes.string.isRequired,
|
||||
passwordResetLink: PropTypes.string.isRequired,
|
||||
errors: PropTypes.object.isRequired,
|
||||
hello: PropTypes.object,
|
||||
query: PropTypes.object.isRequired,
|
||||
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { loading, username, password, errors} = state.login;
|
||||
const { hello, query, passwordResetLink } = state.common;
|
||||
|
||||
return {
|
||||
loading,
|
||||
username,
|
||||
password,
|
||||
errors,
|
||||
hello,
|
||||
query,
|
||||
passwordResetLink
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(withStyles(styles)(Login));
|
||||
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
|
||||
import ResponsiveScreen from '../../components/ResponsiveScreen';
|
||||
import RedirectWithQuery from '../../components/RedirectWithQuery';
|
||||
import { executeHello } from '../../actions/common';
|
||||
|
||||
import Login from './Login';
|
||||
import Chooseaccount from './Chooseaccount';
|
||||
import Consent from './Consent';
|
||||
|
||||
const styles = () => ({
|
||||
});
|
||||
|
||||
class Loginscreen extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
this.props.dispatch(executeHello());
|
||||
}
|
||||
|
||||
render() {
|
||||
const { hello } = this.props;
|
||||
|
||||
const loading = hello === null;
|
||||
return (
|
||||
<ResponsiveScreen loading={loading} withoutPadding={true} >
|
||||
<Switch>
|
||||
<Route path="/identifier" exact component={Login}></Route>
|
||||
<Route path="/chooseaccount" exact component={Chooseaccount}></Route>
|
||||
<Route path="/consent" exact component={Consent}></Route>
|
||||
<RedirectWithQuery target="/identifier"/>
|
||||
</Switch>
|
||||
</ResponsiveScreen>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loginscreen.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
hello: PropTypes.object,
|
||||
|
||||
dispatch: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { hello } = state.common;
|
||||
|
||||
return {
|
||||
hello
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(withStyles(styles)(Loginscreen));
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './Loginscreen';
|
||||
@@ -0,0 +1,92 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
|
||||
import ResponsiveScreen from '../../components/ResponsiveScreen';
|
||||
import { executeLogoff } from '../../actions/common';
|
||||
|
||||
const styles = theme => ({
|
||||
button: {
|
||||
margin: theme.spacing(1),
|
||||
minWidth: 100
|
||||
},
|
||||
subHeader: {
|
||||
marginBottom: theme.spacing(5)
|
||||
}
|
||||
});
|
||||
|
||||
class Welcomescreen extends React.PureComponent {
|
||||
render() {
|
||||
const { classes, hello } = this.props;
|
||||
|
||||
const loading = hello === null;
|
||||
return (
|
||||
<ResponsiveScreen loading={loading}>
|
||||
<Typography variant="h5" component="h3" className="oc-light">
|
||||
<FormattedMessage
|
||||
id="konnect.welcome.headline"
|
||||
defaultMessage="Welcome {displayName}"
|
||||
values={{displayName: hello.displayName}}>
|
||||
</FormattedMessage>
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" className={classes.subHeader + " oc-light"}>
|
||||
{hello.username}
|
||||
</Typography>
|
||||
|
||||
<Typography gutterBottom className="oc-light">
|
||||
<FormattedMessage id="konnect.welcome.message"
|
||||
defaultMessage="You are signed in - awesome!"></FormattedMessage>
|
||||
</Typography>
|
||||
|
||||
<DialogActions>
|
||||
<Button
|
||||
color="secondary"
|
||||
className={classes.button}
|
||||
variant="contained"
|
||||
onClick={(event) => this.logoff(event)}
|
||||
>
|
||||
<FormattedMessage id="konnect.welcome.signoutButton.label" defaultMessage="Sign out"></FormattedMessage>
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</ResponsiveScreen>
|
||||
);
|
||||
}
|
||||
|
||||
logoff(event) {
|
||||
event.preventDefault();
|
||||
|
||||
this.props.dispatch(executeLogoff()).then((response) => {
|
||||
const { history } = this.props;
|
||||
|
||||
if (response.success) {
|
||||
history.push('/identifier');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Welcomescreen.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
|
||||
hello: PropTypes.object,
|
||||
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const { hello } = state.common;
|
||||
|
||||
return {
|
||||
hello
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(withStyles(styles)(Welcomescreen));
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './Welcomescreen';
|
||||
@@ -0,0 +1,68 @@
|
||||
import { injectIntl, defineMessages } from 'react-intl';
|
||||
|
||||
export const ERROR_LOGIN_VALIDATE_MISSINGUSERNAME = 'konnect.error.login.validate.missingUsername';
|
||||
export const ERROR_LOGIN_VALIDATE_MISSINGPASSWORD = 'konnect.error.login.validate.missingPassword';
|
||||
export const ERROR_LOGIN_FAILED = 'konnect.error.login.failed';
|
||||
export const ERROR_HTTP_NETWORK_ERROR = 'konnect.error.http.networkError';
|
||||
export const ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS = 'konnect.error.http.unexpectedResponseStatus';
|
||||
export const ERROR_HTTP_UNEXPECTED_RESPONSE_STATE = 'konnect.error.http.unexpectedResponseState';
|
||||
|
||||
// Translatable error messages.
|
||||
const translations = defineMessages({
|
||||
[ERROR_LOGIN_VALIDATE_MISSINGUSERNAME]: {
|
||||
id: ERROR_LOGIN_VALIDATE_MISSINGUSERNAME,
|
||||
defaultMessage: 'Please enter a valid username'
|
||||
},
|
||||
[ERROR_LOGIN_VALIDATE_MISSINGPASSWORD]: {
|
||||
id: ERROR_LOGIN_VALIDATE_MISSINGPASSWORD,
|
||||
defaultMessage: 'Please enter a valid password'
|
||||
},
|
||||
[ERROR_LOGIN_FAILED]: {
|
||||
id: ERROR_LOGIN_FAILED,
|
||||
defaultMessage: 'Logon failed. Please verify your credentials and try again.'
|
||||
},
|
||||
[ERROR_HTTP_NETWORK_ERROR]: {
|
||||
id: ERROR_HTTP_NETWORK_ERROR,
|
||||
defaultMessage: 'Network error. Please check your connection and try again.'
|
||||
},
|
||||
[ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS]: {
|
||||
id: ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS,
|
||||
defaultMessage: 'Unexpected HTTP response: {status}. Please check your connection and try again.'
|
||||
},
|
||||
[ERROR_HTTP_UNEXPECTED_RESPONSE_STATE]: {
|
||||
id: ERROR_HTTP_UNEXPECTED_RESPONSE_STATE,
|
||||
defaultMessage: 'Unexpected response state: {state}'
|
||||
}
|
||||
});
|
||||
|
||||
// Error with values.
|
||||
export class ExtendedError extends Error {
|
||||
values = undefined;
|
||||
|
||||
constructor(message, values) {
|
||||
super(message);
|
||||
if (Error.captureStackTrace !== undefined) {
|
||||
Error.captureStackTrace(this, ExtendedError);
|
||||
}
|
||||
this.values = values;
|
||||
}
|
||||
}
|
||||
|
||||
// Component to translate error text with values.
|
||||
function ErrorMessageComponent(props) {
|
||||
const { error, intl } = props;
|
||||
|
||||
if (!error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const id = error.id ? error.id : error.message;
|
||||
const messageDescriptor = Object.assign({}, {
|
||||
id,
|
||||
defaultMessage: error.id ? error.message : undefined
|
||||
}, translations[id]);
|
||||
|
||||
return intl.formatMessage(messageDescriptor, error.values);
|
||||
}
|
||||
|
||||
export const ErrorMessage = injectIntl(ErrorMessageComponent);
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
@@ -0,0 +1,13 @@
|
||||
import 'kpop/static/css/base.css';
|
||||
import 'kpop/static/css/scrollbar.css';
|
||||
import './app.css';
|
||||
|
||||
import * as kpop from 'kpop/es/version';
|
||||
|
||||
import * as version from './version';
|
||||
|
||||
console.info(`Kopano Identifier build version: ${version.build}`); // eslint-disable-line no-console
|
||||
console.info(`Kopano Kpop build version: ${kpop.build}`); // eslint-disable-line no-console
|
||||
|
||||
// NOTE(longsleep): Load async, this enables code splitting via Webpack.
|
||||
import(/* webpackChunkName: "identifier-app" */ './app');
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"konnect.loading.error.headline": "Verbindung zum Server fehlgeschlagen",
|
||||
"konnect.login.retryButton.label": "Wiederholen",
|
||||
"konnect.scopeDescription.aliasBasic": "Zugriff auf Ihre grundlegenden Benutzerinformationen",
|
||||
"konnect.scopeDescription.offlineAccess": "Dauerhaften Zugriff (läuft nicht ab)",
|
||||
"konnect.scopeDescription.scope": "Geltungsbereich: {scope}",
|
||||
"konnect.goodbye.headline": "Bis bald",
|
||||
"konnect.goodbye.subHeader": "sie sind jetzt von Ihrem Kopano Konto abgemeldet",
|
||||
"konnect.goodbye.message.close": "Sie können dieses Fenster jetzt schließen.",
|
||||
"konnect.goodbye.confirm.headline": "Hallo {displayName}",
|
||||
"konnect.goodbye.confirm.subHeader": "Bitte bestätigen Sie, dass Sie sich abmelden möchten",
|
||||
"konnect.goodbye.message.confirm": "Klicken Sie auf die Schaltfläche unten um sich aus Ihrem Kopano Konto abzumelden.",
|
||||
"konnect.goodbye.signoutButton.label": "Abmelden",
|
||||
"konnect.welcome.signoutButton.label": "Abmelden",
|
||||
"konnect.chooseaccount.headline": "Konto auswählen",
|
||||
"konnect.chooseaccount.subHeader": "um sich bei Kopano anzumelden",
|
||||
"konnect.chooseaccount.useOther.persona.label": "?",
|
||||
"konnect.chooseaccount.useOther.label": "Anderes Konto",
|
||||
"konnect.consent.headline": "Hi {displayName}",
|
||||
"konnect.consent.message": "{clientDisplayName} möchte",
|
||||
"konnect.consent.tooltip.client": "Wenn Sie \"Einverstanden\" klicken werden Sie zu {redirectURI} weitergeleitet",
|
||||
"konnect.consent.question": "{clientDisplayName} den Zugriff gestatten?",
|
||||
"konnect.consent.consequence": "Wenn Sie Einverstanden klicken, erhält die App Zugriff auf Ihre Informationen.",
|
||||
"konnect.consent.cancelButton.label": "Abbrechen",
|
||||
"konnect.consent.allowButton.label": "Einverstanden",
|
||||
"konnect.login.headline": "Anmelden",
|
||||
"konnect.login.subHeader": "mit Ihrem Kopano Konto",
|
||||
"konnect.login.usernameField.label": "Benutzername",
|
||||
"konnect.login.passwordField.label": "Passwort",
|
||||
"konnect.login.nextButton.label": "Weiter",
|
||||
"konnect.welcome.headline": "Willkommen {displayName}",
|
||||
"konnect.welcome.message": "Sie sind angemeldet - super!",
|
||||
"konnect.error.login.validate.missingUsername": "Geben Sie einen Benutzername ein",
|
||||
"konnect.error.login.validate.missingPassword": "Geben Sie ein Passwort ein",
|
||||
"konnect.error.login.failed": "Anmeldung fehlgeschlagen. Bitte überprüfen Sie Ihre Eingabe und versuchen Sie es noch einmal.",
|
||||
"konnet.error.http.networkError": "Netzwerkfehler. Bitte prüfen Sie Ihre Verbindung und versuchen Sie es noch einmal.",
|
||||
"konnect.error.http.unexpectedResponseStatus": "Unerwartete HTTP-Antwort: {status}. Bitte prüfen Sie Ihre Verbindung und versuchen Sie es noch einmal.",
|
||||
"konnect.error.http.unexpectedResponseState": "Unerwarteter Antwort-Status: {state}"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"konnect.loading.error.headline": "",
|
||||
"konnect.login.retryButton.label": "",
|
||||
"konnect.scopeDescription.aliasBasic": "",
|
||||
"konnect.scopeDescription.offlineAccess": "",
|
||||
"konnect.scopeDescription.scope": "",
|
||||
"konnect.goodbye.headline": "",
|
||||
"konnect.goodbye.subHeader": "",
|
||||
"konnect.goodbye.message.close": "",
|
||||
"konnect.goodbye.confirm.headline": "",
|
||||
"konnect.goodbye.confirm.subHeader": "",
|
||||
"konnect.goodbye.message.confirm": "",
|
||||
"konnect.goodbye.signoutButton.label": "",
|
||||
"konnect.welcome.signoutButton.label": "",
|
||||
"konnect.chooseaccount.headline": "",
|
||||
"konnect.chooseaccount.subHeader": "",
|
||||
"konnect.chooseaccount.useOther.persona.label": "",
|
||||
"konnect.chooseaccount.useOther.label": "",
|
||||
"konnect.consent.headline": "",
|
||||
"konnect.consent.message": "",
|
||||
"konnect.consent.tooltip.client": "",
|
||||
"konnect.consent.question": "",
|
||||
"konnect.consent.consequence": "",
|
||||
"konnect.consent.cancelButton.label": "",
|
||||
"konnect.consent.allowButton.label": "",
|
||||
"konnect.login.headline": "",
|
||||
"konnect.login.subHeader": "",
|
||||
"konnect.login.usernameField.label": "",
|
||||
"konnect.login.passwordField.label": "",
|
||||
"konnect.login.nextButton.label": "",
|
||||
"konnect.welcome.headline": "",
|
||||
"konnect.welcome.message": "",
|
||||
"konnect.error.login.validate.missingUsername": "",
|
||||
"konnect.error.login.validate.missingPassword": "",
|
||||
"konnect.error.login.failed": "",
|
||||
"konnet.error.http.networkError": "",
|
||||
"konnect.error.http.unexpectedResponseStatus": "",
|
||||
"konnect.error.http.unexpectedResponseState": ""
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"konnect.loading.error.headline": "La connexion au serveur a échoué",
|
||||
"konnect.login.retryButton.label": "Réessayer",
|
||||
"konnect.scopeDescription.aliasBasic": "Consulter les informations de base de votre compte",
|
||||
"konnect.scopeDescription.offlineAccess": "Conserver les autorisations d'accès à l'avenir",
|
||||
"konnect.scopeDescription.scope": "Portée : {scope}",
|
||||
"konnect.goodbye.headline": "Au revoir",
|
||||
"konnect.goodbye.subHeader": "vous avez été déconnecté de Kopano",
|
||||
"konnect.goodbye.message.close": "Vous pouvez fermer cette fenêtre à présent.",
|
||||
"konnect.goodbye.confirm.headline": "Bonjour {displayName}",
|
||||
"konnect.goodbye.confirm.subHeader": "Confirmer votre déconnexion",
|
||||
"konnect.goodbye.message.confirm": "Cliquer le bouton ci-dessous, pour quitter Kopano.",
|
||||
"konnect.goodbye.signoutButton.label": "Quitter",
|
||||
"konnect.welcome.signoutButton.label": "Quitter",
|
||||
"konnect.chooseaccount.headline": "Choisir un compte",
|
||||
"konnect.chooseaccount.subHeader": "pour vous authentifier dans Kopano",
|
||||
"konnect.chooseaccount.useOther.persona.label": "?",
|
||||
"konnect.chooseaccount.useOther.label": "Utiliser un autre compte",
|
||||
"konnect.consent.headline": "Bonjour {displayName}",
|
||||
"konnect.consent.message": "{clientDisplayName} souhaite",
|
||||
"konnect.consent.tooltip.client": "En cliquant \"Autoriser\" vous serez redirigé vers : {redirectURI}",
|
||||
"konnect.consent.question": "Autoriser {clientDisplayName} à faire cela ?",
|
||||
"konnect.consent.consequence": "En cliquant, vous autoriser l'app à accéder à vos informations.",
|
||||
"konnect.consent.cancelButton.label": "Annuler",
|
||||
"konnect.consent.allowButton.label": "Autoriser",
|
||||
"konnect.login.headline": "Identification",
|
||||
"konnect.login.subHeader": "avec vos identifiants Kopano",
|
||||
"konnect.login.usernameField.label": "Utilisateur",
|
||||
"konnect.login.passwordField.label": "Mot de passe",
|
||||
"konnect.login.nextButton.label": "Suivant",
|
||||
"konnect.welcome.headline": "Bienvenue {displayName}",
|
||||
"konnect.welcome.message": "Magnifique - Vous êtes connecté !",
|
||||
"konnect.error.login.validate.missingUsername": "Saisir un identifiant",
|
||||
"konnect.error.login.validate.missingPassword": "Saisir un mot de passe",
|
||||
"konnect.error.login.failed": "Echec de connexion. Vérifier vos identifiants et essayer à nouveau.",
|
||||
"konnet.error.http.networkError": "Erreur réseau. Vérifier votre connexion, et réessayer.",
|
||||
"konnect.error.http.unexpectedResponseStatus": "Erreur HTTP inattendue : {status}. Vérifier votre connexion et réessayer.",
|
||||
"konnect.error.http.unexpectedResponseState": "Erreur d'état inattendue : {state}"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"konnect.loading.error.headline": "सर्वर से कनेक्ट करने में विफल",
|
||||
"konnect.login.retryButton.label": "पुन: प्रयास करें",
|
||||
"konnect.scopeDescription.aliasBasic": "अपनी मूल खाता जानकारी देखे",
|
||||
"konnect.scopeDescription.offlineAccess": "अनुमत पहुंच को लगातार और हमेशा बनाए रखें",
|
||||
"konnect.scopeDescription.scope": "क्षेत्र: {scope}",
|
||||
"konnect.goodbye.headline": "अलविदा",
|
||||
"konnect.goodbye.subHeader": "आपको अपने Kopano खाते से साइन आउट कर दिया गया है",
|
||||
"konnect.goodbye.message.close": "अब आप इस विंडो को बंद कर सकते हैं.",
|
||||
"konnect.goodbye.confirm.headline": "नमस्ते {displayName}",
|
||||
"konnect.goodbye.confirm.subHeader": "कृपया साइन आउट की पुष्टि करें",
|
||||
"konnect.goodbye.message.confirm": "अपने Kopano खाते से साइन आउट करने के लिए नीचे दिए गए बटन को दबाएं.",
|
||||
"konnect.goodbye.signoutButton.label": "साइन आउट",
|
||||
"konnect.welcome.signoutButton.label": "साइन आउट",
|
||||
"konnect.chooseaccount.headline": "खाता चुनें",
|
||||
"konnect.chooseaccount.subHeader": "Kopano में साइन इन करने के लिए",
|
||||
"konnect.chooseaccount.useOther.persona.label": "?",
|
||||
"konnect.chooseaccount.useOther.label": "दूसरे खाते का उपयोग करें",
|
||||
"konnect.consent.headline": "नमस्ते {displayName}",
|
||||
"konnect.consent.message": "{clientDisplayName} चाहते है की",
|
||||
"konnect.consent.tooltip.client": "\"अनुमति\" पर क्लिक करने से आपको {redirecturI} पे पुनर्निर्देशित किया जायेगा",
|
||||
"konnect.consent.question": "क्या {clientDisplayName} को ये करने की अनुमति देना चाहते है?",
|
||||
"konnect.consent.consequence": "अनुमति पर क्लिक करके, आप इस एप्लिकेशन को आपकी जानकारी का उपयोग करने की अनुमति देते हैं.",
|
||||
"konnect.consent.cancelButton.label": "रद्द करें",
|
||||
"konnect.consent.allowButton.label": "अनुमति दीजिये",
|
||||
"konnect.login.headline": "साइन इन",
|
||||
"konnect.login.subHeader": "अपने Kopano खाते के साथ",
|
||||
"konnect.login.usernameField.label": "उपयोगकर्ता नाम",
|
||||
"konnect.login.passwordField.label": "पासवर्ड",
|
||||
"konnect.login.nextButton.label": "अगला",
|
||||
"konnect.welcome.headline": "स्वागत हे {displayName}",
|
||||
"konnect.welcome.message": "आप साइंड इन हैं - अद्भुत!",
|
||||
"konnect.error.login.validate.missingUsername": "उपयोगकर्ता नाम डालिये",
|
||||
"konnect.error.login.validate.missingPassword": "पासवर्ड डालिए",
|
||||
"konnect.error.login.failed": "लोगऑन नाकाम रहा. कृपया अपने क्रेडेंशियल्स जांचे और पुनः प्रयास करें.",
|
||||
"konnet.error.http.networkError": "नेटवर्क त्रुटि। कृपया अपने संपर्क की जांच करे और फिर से प्रयास करें.",
|
||||
"konnect.error.http.unexpectedResponseStatus": "अनपेक्षित HTTP प्रतिक्रिया: {status}. कृपया अपने संपर्क की जांच करे और फिर से प्रयास करें.",
|
||||
"konnect.error.http.unexpectedResponseState": "अनपेक्षित प्रतिक्रिया अवस्था: {state}"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"konnect.loading.error.headline": "",
|
||||
"konnect.login.retryButton.label": "",
|
||||
"konnect.scopeDescription.aliasBasic": "",
|
||||
"konnect.scopeDescription.offlineAccess": "",
|
||||
"konnect.scopeDescription.scope": "",
|
||||
"konnect.goodbye.headline": "",
|
||||
"konnect.goodbye.subHeader": "",
|
||||
"konnect.goodbye.message.close": "",
|
||||
"konnect.goodbye.confirm.headline": "",
|
||||
"konnect.goodbye.confirm.subHeader": "",
|
||||
"konnect.goodbye.message.confirm": "",
|
||||
"konnect.goodbye.signoutButton.label": "",
|
||||
"konnect.welcome.signoutButton.label": "",
|
||||
"konnect.chooseaccount.headline": "",
|
||||
"konnect.chooseaccount.subHeader": "",
|
||||
"konnect.chooseaccount.useOther.persona.label": "",
|
||||
"konnect.chooseaccount.useOther.label": "",
|
||||
"konnect.consent.headline": "",
|
||||
"konnect.consent.message": "",
|
||||
"konnect.consent.tooltip.client": "",
|
||||
"konnect.consent.question": "",
|
||||
"konnect.consent.consequence": "",
|
||||
"konnect.consent.cancelButton.label": "",
|
||||
"konnect.consent.allowButton.label": "",
|
||||
"konnect.login.headline": "",
|
||||
"konnect.login.subHeader": "",
|
||||
"konnect.login.usernameField.label": "",
|
||||
"konnect.login.passwordField.label": "",
|
||||
"konnect.login.nextButton.label": "",
|
||||
"konnect.welcome.headline": "",
|
||||
"konnect.welcome.message": "",
|
||||
"konnect.error.login.validate.missingUsername": "",
|
||||
"konnect.error.login.validate.missingPassword": "",
|
||||
"konnect.error.login.failed": "",
|
||||
"konnet.error.http.networkError": "",
|
||||
"konnect.error.http.unexpectedResponseStatus": "",
|
||||
"konnect.error.http.unexpectedResponseState": ""
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"konnect.loading.error.headline": "",
|
||||
"konnect.login.retryButton.label": "",
|
||||
"konnect.scopeDescription.aliasBasic": "",
|
||||
"konnect.scopeDescription.offlineAccess": "",
|
||||
"konnect.scopeDescription.scope": "",
|
||||
"konnect.goodbye.headline": "",
|
||||
"konnect.goodbye.subHeader": "",
|
||||
"konnect.goodbye.message.close": "",
|
||||
"konnect.goodbye.confirm.headline": "",
|
||||
"konnect.goodbye.confirm.subHeader": "",
|
||||
"konnect.goodbye.message.confirm": "",
|
||||
"konnect.goodbye.signoutButton.label": "",
|
||||
"konnect.welcome.signoutButton.label": "",
|
||||
"konnect.chooseaccount.headline": "",
|
||||
"konnect.chooseaccount.subHeader": "",
|
||||
"konnect.chooseaccount.useOther.persona.label": "",
|
||||
"konnect.chooseaccount.useOther.label": "",
|
||||
"konnect.consent.headline": "",
|
||||
"konnect.consent.message": "",
|
||||
"konnect.consent.tooltip.client": "",
|
||||
"konnect.consent.question": "",
|
||||
"konnect.consent.consequence": "",
|
||||
"konnect.consent.cancelButton.label": "",
|
||||
"konnect.consent.allowButton.label": "",
|
||||
"konnect.login.headline": "",
|
||||
"konnect.login.subHeader": "",
|
||||
"konnect.login.usernameField.label": "",
|
||||
"konnect.login.passwordField.label": "",
|
||||
"konnect.login.nextButton.label": "",
|
||||
"konnect.welcome.headline": "",
|
||||
"konnect.welcome.message": "",
|
||||
"konnect.error.login.validate.missingUsername": "",
|
||||
"konnect.error.login.validate.missingPassword": "",
|
||||
"konnect.error.login.failed": "",
|
||||
"konnet.error.http.networkError": "",
|
||||
"konnect.error.http.unexpectedResponseStatus": "",
|
||||
"konnect.error.http.unexpectedResponseState": ""
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user