mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 23:49:45 -05:00
🎉 Add the ability to create demo user on demand.
This commit is contained in:
parent
b0ca6493e3
commit
e42ccf932e
12 changed files with 285 additions and 199 deletions
|
@ -3,7 +3,7 @@ CREATE TABLE users (
|
|||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
deleted_at timestamptz NULL,
|
||||
|
||||
fullname text NOT NULL DEFAULT '',
|
||||
username text NOT NULL,
|
||||
|
@ -11,7 +11,8 @@ CREATE TABLE users (
|
|||
photo text NOT NULL,
|
||||
password text NOT NULL,
|
||||
|
||||
metadata bytea NULL DEFAULT NULL
|
||||
lang text NULL,
|
||||
is_demo boolean NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_attrs (
|
||||
|
@ -31,7 +32,7 @@ CREATE TABLE IF NOT EXISTS tokens (
|
|||
token text NOT NULL,
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
used_at timestamptz DEFAULT NULL,
|
||||
used_at timestamptz NULL,
|
||||
|
||||
PRIMARY KEY (token, user_id)
|
||||
);
|
||||
|
@ -43,27 +44,31 @@ CREATE TABLE IF NOT EXISTS sessions (
|
|||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
|
||||
user_id uuid REFERENCES users(id) ON DELETE CASCADE,
|
||||
user_agent TEXT NULL
|
||||
user_agent text NULL
|
||||
);
|
||||
|
||||
-- Insert a placeholder system user.
|
||||
|
||||
INSERT INTO users (id, fullname, username, email, photo, password, metadata)
|
||||
INSERT INTO users (id, fullname, username, email, photo, password)
|
||||
VALUES ('00000000-0000-0000-0000-000000000000'::uuid,
|
||||
'System User',
|
||||
'00000000-0000-0000-0000-000000000000',
|
||||
'system@uxbox.io',
|
||||
'',
|
||||
'!',
|
||||
'{}');
|
||||
'!');
|
||||
|
||||
CREATE UNIQUE INDEX users__username__idx
|
||||
ON users (username)
|
||||
WHERE deleted_at is null;
|
||||
WHERE deleted_at IS null;
|
||||
|
||||
CREATE UNIQUE INDEX users__email__idx
|
||||
ON users (email)
|
||||
WHERE deleted_at is null;
|
||||
WHERE deleted_at IS null;
|
||||
|
||||
CREATE INDEX users__is_demo
|
||||
ON users(is_demo)
|
||||
WHERE deleted_at IS null
|
||||
AND is_demo IS true;
|
||||
|
||||
CREATE TRIGGER users__modified_at__tgr
|
||||
BEFORE UPDATE ON users
|
||||
|
|
|
@ -8,8 +8,7 @@ CREATE TABLE IF NOT EXISTS projects (
|
|||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
name text NOT NULL,
|
||||
metadata bytea NULL DEFAULT NULL
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS project_users (
|
||||
|
@ -33,9 +32,7 @@ CREATE TABLE IF NOT EXISTS project_files (
|
|||
|
||||
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
modified_at timestamptz NOT NULL DEFAULT clock_timestamp(),
|
||||
deleted_at timestamptz DEFAULT NULL,
|
||||
|
||||
metadata bytea NULL DEFAULT NULL
|
||||
deleted_at timestamptz DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS project_file_users (
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
:smtp-ssl (lookup-env env :uxbox-smtp-ssl false)
|
||||
:smtp-enabled (lookup-env env :uxbox-smtp-enabled false)
|
||||
|
||||
:allow-demo-users (lookup-env env :uxbox-allow-demo-users true)
|
||||
:registration-enabled (lookup-env env :uxbox-registration-enabled true)})
|
||||
|
||||
(defn read-test-config
|
||||
|
|
|
@ -77,7 +77,6 @@
|
|||
(> user-index 0))
|
||||
(create-additional-project-user conn [project-index user-index])))))
|
||||
|
||||
|
||||
;; --- Create Page Files
|
||||
|
||||
(def create-file-sql
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
(derive :logout ::unauthenticated)
|
||||
(derive :register-profile ::unauthenticated)
|
||||
(derive :request-profile-recovery ::unauthenticated)
|
||||
(derive :recover-profile ::unauthenticated)))
|
||||
(derive :recover-profile ::unauthenticated)
|
||||
(derive :create-demo-profile ::unauthenticated)))
|
||||
|
||||
(def query-types-hierarchy
|
||||
(make-hierarchy))
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
(require 'uxbox.services.queries.projects)
|
||||
(require 'uxbox.services.queries.project-files)
|
||||
(require 'uxbox.services.queries.project-pages)
|
||||
(require 'uxbox.services.queries.users)
|
||||
(require 'uxbox.services.queries.profile)
|
||||
(require 'uxbox.services.queries.user-attrs))
|
||||
|
||||
(defn- load-mutation-services
|
||||
|
|
52
backend/src/uxbox/services/mutations/demo.clj
Normal file
52
backend/src/uxbox/services/mutations/demo.clj
Normal file
|
@ -0,0 +1,52 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2016-2020 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.services.mutations.demo
|
||||
"A demo specific mutations."
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[datoteka.core :as fs]
|
||||
[datoteka.storages :as ds]
|
||||
[promesa.core :as p]
|
||||
[promesa.exec :as px]
|
||||
[sodi.prng]
|
||||
[sodi.pwhash]
|
||||
[sodi.util]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.config :as cfg]
|
||||
[uxbox.db :as db]
|
||||
[uxbox.emails :as emails]
|
||||
[uxbox.images :as images]
|
||||
[uxbox.media :as media]
|
||||
[uxbox.services.mutations :as sm]
|
||||
[uxbox.services.util :as su]
|
||||
[uxbox.services.mutations.profile :as profile]
|
||||
[uxbox.util.blob :as blob]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[vertx.core :as vc]))
|
||||
|
||||
(su/defstr sql:create-demo-user
|
||||
"insert into users (id, fullname, username, email, password, photo, is_demo)
|
||||
values ($1, $2, $3, $4, $5, '', true) returning *")
|
||||
|
||||
(sm/defmutation ::create-demo-profile
|
||||
[params]
|
||||
(let [id (uuid/next)
|
||||
sem (System/currentTimeMillis)
|
||||
username (str "demo-" sem)
|
||||
email (str username ".demo@uxbox.io")
|
||||
fullname (str "Demo User " sem)
|
||||
password (-> (sodi.prng/random-bytes 12)
|
||||
(sodi.util/bytes->b64s))
|
||||
password' (sodi.pwhash/derive password)]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(db/query-one conn [sql:create-demo-user id fullname username email password'])
|
||||
{:username username
|
||||
:password password})))
|
|
@ -26,10 +26,7 @@
|
|||
[uxbox.media :as media]
|
||||
[uxbox.services.mutations :as sm]
|
||||
[uxbox.services.util :as su]
|
||||
[uxbox.services.queries.users :refer [get-profile
|
||||
decode-profile-row
|
||||
strip-private-attrs
|
||||
resolve-thumbnail]]
|
||||
[uxbox.services.queries.profile :as profile]
|
||||
[uxbox.util.blob :as blob]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[vertx.core :as vc]))
|
||||
|
@ -125,8 +122,7 @@
|
|||
email fullname (blob/encode metadata)]]
|
||||
(-> (db/query-one conn sqlv)
|
||||
(p/then' su/raise-not-found-if-nil)
|
||||
(p/then' decode-profile-row)
|
||||
(p/then' strip-private-attrs))))
|
||||
(p/then' profile/strip-private-attrs))))
|
||||
|
||||
(s/def ::update-profile
|
||||
(s/keys :req-un [::id ::username ::email ::fullname ::metadata]))
|
||||
|
@ -142,7 +138,7 @@
|
|||
|
||||
(defn- validate-password
|
||||
[conn {:keys [user old-password] :as params}]
|
||||
(p/let [profile (get-profile conn user)
|
||||
(p/let [profile (profile/retrieve-profile conn user)
|
||||
result (sodi.pwhash/verify old-password (:password profile))]
|
||||
(when-not (:valid result)
|
||||
(ex/raise :type :validation
|
||||
|
@ -205,8 +201,7 @@
|
|||
returning id, photo"]
|
||||
(-> (db/query-one db/pool [sql (str path) user])
|
||||
(p/then' su/raise-not-found-if-nil)
|
||||
;; (p/then' strip-private-attrs)
|
||||
(p/then resolve-thumbnail))))]
|
||||
(p/then profile/resolve-thumbnail))))]
|
||||
|
||||
(when-not (valid-image-types? (:mtype file))
|
||||
(ex/raise :type :validation
|
||||
|
@ -218,9 +213,9 @@
|
|||
|
||||
;; --- Mutation: Register Profile
|
||||
|
||||
(def ^:private create-user-sql
|
||||
"insert into users (id, fullname, username, email, password, metadata, photo)
|
||||
values ($1, $2, $3, $4, $5, $6, '') returning *")
|
||||
(su/defstr sql:create-user
|
||||
"insert into users (id, fullname, username, email, password, photo)
|
||||
values ($1, $2, $3, $4, $5, '') returning *")
|
||||
|
||||
(defn- check-profile-existence!
|
||||
[conn {:keys [username email] :as params}]
|
||||
|
@ -239,24 +234,21 @@
|
|||
(defn create-profile
|
||||
"Create the user entry on the database with limited input
|
||||
filling all the other fields with defaults."
|
||||
[conn {:keys [id username fullname email password metadata] :as params}]
|
||||
[conn {:keys [id username fullname email password] :as params}]
|
||||
(let [id (or id (uuid/next))
|
||||
metadata (blob/encode metadata)
|
||||
password (sodi.pwhash/derive password)
|
||||
sqlv [create-user-sql
|
||||
sqlv [sql:create-user
|
||||
id
|
||||
fullname
|
||||
username
|
||||
email
|
||||
password
|
||||
metadata]]
|
||||
(-> (db/query-one conn sqlv)
|
||||
(p/then' decode-profile-row))))
|
||||
password]]
|
||||
(db/query-one conn sqlv)))
|
||||
|
||||
(defn register-profile
|
||||
[conn params]
|
||||
(-> (create-profile conn params)
|
||||
(p/then' strip-private-attrs)
|
||||
(p/then' profile/strip-private-attrs)
|
||||
(p/then (fn [profile]
|
||||
(-> (emails/send! emails/register {:to (:email params)
|
||||
:name (:fullname params)})
|
||||
|
@ -328,3 +320,5 @@
|
|||
(db/with-atomic [conn db/pool]
|
||||
(-> (validate-token conn token)
|
||||
(p/then (fn [user-id] (update-password conn user-id)))))))
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2016 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.services.queries.users
|
||||
(ns uxbox.services.queries.profile
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
|
@ -18,7 +18,6 @@
|
|||
|
||||
;; --- Helpers & Specs
|
||||
|
||||
(declare decode-profile-row)
|
||||
(declare strip-private-attrs)
|
||||
|
||||
(s/def ::email ::us/email)
|
||||
|
@ -42,28 +41,21 @@
|
|||
(-> (px/submit! #(images/populate-thumbnails user opts))
|
||||
(su/handle-on-context))))
|
||||
|
||||
(defn get-profile
|
||||
(defn retrieve-profile
|
||||
[conn id]
|
||||
(let [sql "select * from users where id=$1 and deleted_at is null"]
|
||||
(-> (db/query-one db/pool [sql id])
|
||||
(p/then' decode-profile-row))))
|
||||
(db/query-one db/pool [sql id])))
|
||||
|
||||
(s/def ::profile
|
||||
(s/keys :req-un [::user]))
|
||||
|
||||
(sq/defquery ::profile
|
||||
[{:keys [user] :as params}]
|
||||
(-> (get-profile db/pool user)
|
||||
(-> (retrieve-profile db/pool user)
|
||||
(p/then' strip-private-attrs)))
|
||||
|
||||
;; --- Attrs Helpers
|
||||
|
||||
(defn decode-profile-row
|
||||
[{:keys [metadata] :as row}]
|
||||
(when row
|
||||
(cond-> row
|
||||
metadata (assoc :metadata (blob/decode metadata)))))
|
||||
|
||||
(defn strip-private-attrs
|
||||
"Only selects a publicy visible user attrs."
|
||||
[profile]
|
|
@ -1,97 +1,4 @@
|
|||
{
|
||||
"auth.email-or-username" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/login.cljs:61" ],
|
||||
"translations" : {
|
||||
"en" : "Email or Username",
|
||||
"fr" : "adresse email ou nom d'utilisateur"
|
||||
}
|
||||
},
|
||||
"auth.forgot-password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/login.cljs:83" ],
|
||||
"translations" : {
|
||||
"en" : "Forgot your password?",
|
||||
"fr" : "Mot de passe oublié ?"
|
||||
}
|
||||
},
|
||||
|
||||
"profile.recovery.password-changed" : {
|
||||
"used-in" : [ "src/uxbox/main/data/auth.cljs:178" ],
|
||||
"translations" : {
|
||||
"en" : "Password successfully changed",
|
||||
"fr" : "TODO"
|
||||
}
|
||||
},
|
||||
|
||||
"profile.recovery.username-or-email": {
|
||||
"translations" : {
|
||||
"en" : "Username or Email Address",
|
||||
"fr" : "adresse email ou nom d'utilisateur"
|
||||
}
|
||||
},
|
||||
|
||||
"profile.recovery.token": {
|
||||
"translations" : {
|
||||
"en" : "Recovery token (sent by email)",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
|
||||
"profile.recovery.password": {
|
||||
"translations" : {
|
||||
"en" : "Type a new password",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
|
||||
"profile.recovery.submit-request": {
|
||||
"translations" : {
|
||||
"en" : "Recover Password",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
|
||||
"profile.recovery.submit-recover": {
|
||||
"translations" : {
|
||||
"en" : "Change your password",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
|
||||
"profile.recovery.go-to-login": {
|
||||
"translations" : {
|
||||
"en" : "Go back!",
|
||||
"fr" : "Retour!"
|
||||
}
|
||||
},
|
||||
|
||||
"profile.recovery.recovery-token-sent" : {
|
||||
"used-in" : [ "src/uxbox/main/data/auth.cljs:141" ],
|
||||
"translations" : {
|
||||
"en" : "Password recovery link sent to your inbox.",
|
||||
"fr" : "Lien de récupération de mot de passe envoyé."
|
||||
}
|
||||
},
|
||||
"auth.no-account" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/login.cljs:86" ],
|
||||
"translations" : {
|
||||
"en" : "Don't have an account?",
|
||||
"fr" : "Vous n'avez pas de compte ?"
|
||||
}
|
||||
},
|
||||
"auth.password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/login.cljs:70" ],
|
||||
"translations" : {
|
||||
"en" : "Password",
|
||||
"fr" : "Mot de passe"
|
||||
}
|
||||
},
|
||||
"auth.signin" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/login.cljs:77" ],
|
||||
"translations" : {
|
||||
"en" : "Sign in",
|
||||
"fr" : "Se connecter"
|
||||
}
|
||||
},
|
||||
"ds.accept" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/history.cljs:113" ],
|
||||
"translations" : {
|
||||
|
@ -107,14 +14,21 @@
|
|||
}
|
||||
},
|
||||
"ds.color-lightbox.add" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:52" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:49", "src/uxbox/main/ui/dashboard/colors.cljs:52" ],
|
||||
"translations" : {
|
||||
"en" : "+ Add color",
|
||||
"fr" : "+ Ajouter couleur"
|
||||
}
|
||||
},
|
||||
"ds.color-lightbox.title" : {
|
||||
"translations" : {
|
||||
"en" : null,
|
||||
"fr" : null
|
||||
},
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:43" ]
|
||||
},
|
||||
"ds.color-new" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:149" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:146", "src/uxbox/main/ui/dashboard/colors.cljs:149" ],
|
||||
"translations" : {
|
||||
"en" : "+ New color",
|
||||
"fr" : "+ Nouvelle couleur"
|
||||
|
@ -128,7 +42,7 @@
|
|||
}
|
||||
},
|
||||
"ds.colors-collection.new" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:134" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:131", "src/uxbox/main/ui/dashboard/colors.cljs:134" ],
|
||||
"translations" : {
|
||||
"en" : "+ New library",
|
||||
"fr" : "+ Nouvelle librairie"
|
||||
|
@ -233,35 +147,35 @@
|
|||
}
|
||||
},
|
||||
"ds.multiselect-bar.copy" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:196", "src/uxbox/main/ui/dashboard/images.cljs:171", "src/uxbox/main/ui/dashboard/colors.cljs:224", "src/uxbox/main/ui/dashboard/colors.cljs:201" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:221", "src/uxbox/main/ui/dashboard/colors.cljs:198", "src/uxbox/main/ui/dashboard/images.cljs:196", "src/uxbox/main/ui/dashboard/images.cljs:171", "src/uxbox/main/ui/dashboard/colors.cljs:224", "src/uxbox/main/ui/dashboard/colors.cljs:201" ],
|
||||
"translations" : {
|
||||
"en" : "Copy",
|
||||
"fr" : "Copier"
|
||||
}
|
||||
},
|
||||
"ds.multiselect-bar.copy-to-library" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:200", "src/uxbox/main/ui/dashboard/images.cljs:175", "src/uxbox/main/ui/dashboard/colors.cljs:228", "src/uxbox/main/ui/dashboard/colors.cljs:205" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:225", "src/uxbox/main/ui/dashboard/colors.cljs:202", "src/uxbox/main/ui/dashboard/images.cljs:200", "src/uxbox/main/ui/dashboard/images.cljs:175", "src/uxbox/main/ui/dashboard/colors.cljs:228", "src/uxbox/main/ui/dashboard/colors.cljs:205" ],
|
||||
"translations" : {
|
||||
"en" : "Copy to library",
|
||||
"fr" : "Copier vers la librairie"
|
||||
}
|
||||
},
|
||||
"ds.multiselect-bar.delete" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:190", "src/uxbox/main/ui/dashboard/colors.cljs:217" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:214", "src/uxbox/main/ui/dashboard/images.cljs:190", "src/uxbox/main/ui/dashboard/colors.cljs:217" ],
|
||||
"translations" : {
|
||||
"en" : "Delete",
|
||||
"fr" : "Supprimer"
|
||||
}
|
||||
},
|
||||
"ds.multiselect-bar.move" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:179", "src/uxbox/main/ui/dashboard/colors.cljs:209" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:206", "src/uxbox/main/ui/dashboard/images.cljs:179", "src/uxbox/main/ui/dashboard/colors.cljs:209" ],
|
||||
"translations" : {
|
||||
"en" : "Move",
|
||||
"fr" : "Déplacer"
|
||||
}
|
||||
},
|
||||
"ds.multiselect-bar.move-to-library" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:183", "src/uxbox/main/ui/dashboard/colors.cljs:213" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:210", "src/uxbox/main/ui/dashboard/images.cljs:183", "src/uxbox/main/ui/dashboard/colors.cljs:213" ],
|
||||
"translations" : {
|
||||
"en" : "Move to library",
|
||||
"fr" : "Déplacer vers la librairie"
|
||||
|
@ -275,7 +189,7 @@
|
|||
}
|
||||
},
|
||||
"ds.new-file" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:143" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:142", "src/uxbox/main/ui/dashboard/projects.cljs:143" ],
|
||||
"translations" : {
|
||||
"en" : "+ New File",
|
||||
"fr" : null
|
||||
|
@ -303,7 +217,7 @@
|
|||
}
|
||||
},
|
||||
"ds.search.placeholder" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:192" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:191", "src/uxbox/main/ui/dashboard/projects.cljs:192" ],
|
||||
"translations" : {
|
||||
"en" : "Search...",
|
||||
"fr" : "Rechercher..."
|
||||
|
@ -316,13 +230,6 @@
|
|||
"fr" : null
|
||||
}
|
||||
},
|
||||
"workspace.sidebar.layers" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/layers.cljs:260" ],
|
||||
"translations" : {
|
||||
"en" : "Layers",
|
||||
"fr" : "Couches"
|
||||
}
|
||||
},
|
||||
"ds.size" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/icon_measures.cljs:33" ],
|
||||
"translations" : {
|
||||
|
@ -331,7 +238,7 @@
|
|||
}
|
||||
},
|
||||
"ds.store-colors-title" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:129" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:126", "src/uxbox/main/ui/dashboard/colors.cljs:129" ],
|
||||
"translations" : {
|
||||
"en" : "COLORS STORE",
|
||||
"fr" : "BOUTIQUE"
|
||||
|
@ -352,14 +259,14 @@
|
|||
}
|
||||
},
|
||||
"ds.updated-at" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:110" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/projects.cljs:109", "src/uxbox/main/ui/dashboard/projects.cljs:110" ],
|
||||
"translations" : {
|
||||
"en" : "Updated %s",
|
||||
"fr" : "Mis à jour %s"
|
||||
}
|
||||
},
|
||||
"ds.uploaded-at" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/images.cljs:237", "src/uxbox/main/ui/dashboard/icons.cljs:303" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/icons.cljs:303", "src/uxbox/main/ui/dashboard/images.cljs:237" ],
|
||||
"translations" : {
|
||||
"en" : "Uploaded at %s",
|
||||
"fr" : "Mise en ligne : %s"
|
||||
|
@ -401,7 +308,7 @@
|
|||
}
|
||||
},
|
||||
"ds.your-colors-title" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:126" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/dashboard/colors.cljs:123", "src/uxbox/main/ui/dashboard/colors.cljs:126" ],
|
||||
"translations" : {
|
||||
"en" : "YOUR COLORS",
|
||||
"fr" : "VOS COULEURS"
|
||||
|
@ -429,42 +336,35 @@
|
|||
}
|
||||
},
|
||||
"errors.api.form.registration-disabled" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/register.cljs:39" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/register.cljs:39", "src/uxbox/main/ui/auth/register.cljs:39" ],
|
||||
"translations" : {
|
||||
"en" : "The registration is currently disabled.",
|
||||
"fr" : "L'enregistrement est actuellement désactivé."
|
||||
}
|
||||
},
|
||||
"errors.api.form.unexpected-error" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/register.cljs:51" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/register.cljs:51", "src/uxbox/main/ui/auth/register.cljs:51" ],
|
||||
"translations" : {
|
||||
"en" : "An unexpected error occurred.",
|
||||
"fr" : "Une erreur inattendue c'est produite"
|
||||
}
|
||||
},
|
||||
"profile.recovery.invalid-token" : {
|
||||
"used-in" : [ "src/uxbox/main/data/auth.cljs:174", "src/uxbox/main/data/auth.cljs:151" ],
|
||||
"translations" : {
|
||||
"en" : "The recovery token is invalid.",
|
||||
"fr" : "Le jeton de récupération n'est pas valide."
|
||||
}
|
||||
},
|
||||
"errors.auth.unauthorized" : {
|
||||
"used-in" : [ "src/uxbox/main/data/auth.cljs:59" ],
|
||||
"used-in" : [ "src/uxbox/main/data/auth.cljs:62", "src/uxbox/main/data/auth.cljs:59" ],
|
||||
"translations" : {
|
||||
"en" : "Username or password seems to be wrong.",
|
||||
"fr" : "Le nom d'utilisateur ou le mot de passe semble être faux."
|
||||
}
|
||||
},
|
||||
"errors.generic" : {
|
||||
"used-in" : [ "src/uxbox/main/ui.cljs:86" ],
|
||||
"used-in" : [ "src/uxbox/main/ui.cljs:127", "src/uxbox/main/ui.cljs:86" ],
|
||||
"translations" : {
|
||||
"en" : "Something wrong has happened.",
|
||||
"fr" : "Quelque chose c'est mal passé."
|
||||
}
|
||||
},
|
||||
"errors.network" : {
|
||||
"used-in" : [ "src/uxbox/main/ui.cljs:80" ],
|
||||
"used-in" : [ "src/uxbox/main/ui.cljs:121", "src/uxbox/main/ui.cljs:80" ],
|
||||
"translations" : {
|
||||
"en" : "Unable to connect to backend server.",
|
||||
"fr" : "Impossible de se connecter au serveur principal."
|
||||
|
@ -512,34 +412,160 @@
|
|||
"fr" : "Envoyer un fichier"
|
||||
}
|
||||
},
|
||||
"login.create-demo-profile" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/login.cljs:92" ],
|
||||
"translations" : {
|
||||
"en" : "Create demo account",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
"login.create-demo-profile-description" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/login.cljs:91" ],
|
||||
"translations" : {
|
||||
"en" : "Will be deleted in 24 hours since creation",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
"login.email-or-username" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/login.cljs:63", "src/uxbox/main/ui/auth/login.cljs:61" ],
|
||||
"translations" : {
|
||||
"en" : "Email or Username",
|
||||
"fr" : "adresse email ou nom d'utilisateur"
|
||||
}
|
||||
},
|
||||
"login.forgot-password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/login.cljs:85", "src/uxbox/main/ui/auth/login.cljs:83" ],
|
||||
"translations" : {
|
||||
"en" : "Forgot your password?",
|
||||
"fr" : "Mot de passe oublié ?"
|
||||
}
|
||||
},
|
||||
"login.password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/login.cljs:72", "src/uxbox/main/ui/auth/login.cljs:70" ],
|
||||
"translations" : {
|
||||
"en" : "Password",
|
||||
"fr" : "Mot de passe"
|
||||
}
|
||||
},
|
||||
"login.register" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/login.cljs:88", "src/uxbox/main/ui/auth/login.cljs:86" ],
|
||||
"translations" : {
|
||||
"en" : "Don't have an account?",
|
||||
"fr" : "Vous n'avez pas de compte ?"
|
||||
}
|
||||
},
|
||||
"login.submit" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/login.cljs:79", "src/uxbox/main/ui/auth/login.cljs:77" ],
|
||||
"translations" : {
|
||||
"en" : "Sign in",
|
||||
"fr" : "Se connecter"
|
||||
}
|
||||
},
|
||||
"profile.recovery.go-to-login" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:81", "src/uxbox/main/ui/profile/recovery_request.cljs:64" ],
|
||||
"translations" : {
|
||||
"en" : "Go back!",
|
||||
"fr" : "Retour!"
|
||||
}
|
||||
},
|
||||
"profile.recovery.invalid-token" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:45", "src/uxbox/main/data/auth.cljs:174", "src/uxbox/main/data/auth.cljs:151" ],
|
||||
"translations" : {
|
||||
"en" : "The recovery token is invalid.",
|
||||
"fr" : "Le jeton de récupération n'est pas valide."
|
||||
}
|
||||
},
|
||||
"profile.recovery.password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:70" ],
|
||||
"translations" : {
|
||||
"en" : "Type a new password",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
"profile.recovery.password-changed" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:40", "src/uxbox/main/data/auth.cljs:178" ],
|
||||
"translations" : {
|
||||
"en" : "Password successfully changed",
|
||||
"fr" : "TODO"
|
||||
}
|
||||
},
|
||||
"profile.recovery.recovery-token-sent" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:38", "src/uxbox/main/data/auth.cljs:141" ],
|
||||
"translations" : {
|
||||
"en" : "Password recovery link sent to your inbox.",
|
||||
"fr" : "Lien de récupération de mot de passe envoyé."
|
||||
}
|
||||
},
|
||||
"profile.recovery.submit-recover" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:76" ],
|
||||
"translations" : {
|
||||
"en" : "Change your password",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
"profile.recovery.submit-request" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:59" ],
|
||||
"translations" : {
|
||||
"en" : "Recover Password",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
"profile.recovery.token" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery.cljs:61" ],
|
||||
"translations" : {
|
||||
"en" : "Recovery token (sent by email)",
|
||||
"fr" : null
|
||||
}
|
||||
},
|
||||
"profile.recovery.username-or-email" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/recovery_request.cljs:53" ],
|
||||
"translations" : {
|
||||
"en" : "Username or Email Address",
|
||||
"fr" : "adresse email ou nom d'utilisateur"
|
||||
}
|
||||
},
|
||||
"profile.register.already-have-account" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/register.cljs:131" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/register.cljs:131", "src/uxbox/main/ui/auth/register.cljs:131" ],
|
||||
"translations" : {
|
||||
"en" : "Already have an account?",
|
||||
"fr" : "Vous avez déjà un compte ?"
|
||||
}
|
||||
},
|
||||
"profile.register.email" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/register.cljs:101", "src/uxbox/main/ui/settings/profile.cljs:111", "src/uxbox/main/ui/auth/register.cljs:101" ],
|
||||
"translations" : {
|
||||
"en" : "Your email",
|
||||
"fr" : "Votre adresse email"
|
||||
}
|
||||
},
|
||||
"profile.register.fullname" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/register.cljs:72" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/register.cljs:72", "src/uxbox/main/ui/auth/register.cljs:72" ],
|
||||
"translations" : {
|
||||
"en" : "Full Name",
|
||||
"fr" : "Nom complet"
|
||||
}
|
||||
},
|
||||
"profile.register.get-started" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/register.cljs:127" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/register.cljs:127", "src/uxbox/main/ui/auth/register.cljs:127" ],
|
||||
"translations" : {
|
||||
"en" : "Get started",
|
||||
"fr" : "Commencer"
|
||||
}
|
||||
},
|
||||
"profile.register.password" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/auth/register.cljs:115" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/register.cljs:115", "src/uxbox/main/ui/auth/register.cljs:115" ],
|
||||
"translations" : {
|
||||
"en" : "Password",
|
||||
"fr" : "Mot de passe"
|
||||
}
|
||||
},
|
||||
"profile.register.username" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/profile/register.cljs:87", "src/uxbox/main/ui/settings/profile.cljs:98", "src/uxbox/main/ui/auth/register.cljs:87" ],
|
||||
"translations" : {
|
||||
"en" : "Your username",
|
||||
"fr" : "Votre nom d'utilisateur"
|
||||
}
|
||||
},
|
||||
"settings.notifications" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/header.cljs:43" ],
|
||||
"translations" : {
|
||||
|
@ -659,12 +685,12 @@
|
|||
"fr" : "Votre avatar"
|
||||
}
|
||||
},
|
||||
"profile.register.email" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:111", "src/uxbox/main/ui/auth/register.cljs:101" ],
|
||||
"settings.profile.your-email" : {
|
||||
"translations" : {
|
||||
"en" : "Your email",
|
||||
"fr" : "Votre adresse email"
|
||||
}
|
||||
"en" : null,
|
||||
"fr" : null
|
||||
},
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:111" ]
|
||||
},
|
||||
"settings.profile.your-name" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:86" ],
|
||||
|
@ -673,12 +699,12 @@
|
|||
"fr" : "Votre nom complet"
|
||||
}
|
||||
},
|
||||
"profile.register.username" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:98", "src/uxbox/main/ui/auth/register.cljs:87" ],
|
||||
"settings.profile.your-username" : {
|
||||
"translations" : {
|
||||
"en" : "Your username",
|
||||
"fr" : "Votre nom d'utilisateur"
|
||||
}
|
||||
"en" : null,
|
||||
"fr" : null
|
||||
},
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:98" ]
|
||||
},
|
||||
"settings.update-settings" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/settings/profile.cljs:130", "src/uxbox/main/ui/settings/password.cljs:86", "src/uxbox/main/ui/settings/notifications.cljs:42" ],
|
||||
|
@ -793,7 +819,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.color" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:81", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:125", "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:47" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/stroke.cljs:81", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:124", "src/uxbox/main/ui/workspace/sidebar/options/fill.cljs:47", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:125" ],
|
||||
"translations" : {
|
||||
"en" : "Color",
|
||||
"fr" : "Couleur"
|
||||
|
@ -821,7 +847,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.grid-options" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:113" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:112", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:113" ],
|
||||
"translations" : {
|
||||
"en" : "Grid settings",
|
||||
"fr" : "Paramètres de la grille"
|
||||
|
@ -863,7 +889,7 @@
|
|||
}
|
||||
},
|
||||
"workspace.options.size" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:72", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:66", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:115", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:38" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/options/text.cljs:72", "src/uxbox/main/ui/workspace/sidebar/options/rect.cljs:66", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:114", "src/uxbox/main/ui/workspace/sidebar/options/circle.cljs:69", "src/uxbox/main/ui/workspace/sidebar/options/image.cljs:64", "src/uxbox/main/ui/workspace/sidebar/options/measures.cljs:38", "src/uxbox/main/ui/workspace/sidebar/options/page.cljs:115" ],
|
||||
"translations" : {
|
||||
"en" : "Size",
|
||||
"fr" : "Taille"
|
||||
|
@ -925,8 +951,15 @@
|
|||
"fr" : "Alignement de texte"
|
||||
}
|
||||
},
|
||||
"workspace.sidebar.layers" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/layers.cljs:261", "src/uxbox/main/ui/workspace/sidebar/layers.cljs:260" ],
|
||||
"translations" : {
|
||||
"en" : "Layers",
|
||||
"fr" : "Couches"
|
||||
}
|
||||
},
|
||||
"workspace.sidebar.sitemap" : {
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/sitemap.cljs:134" ],
|
||||
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/sitemap.cljs:135", "src/uxbox/main/ui/workspace/sidebar/sitemap.cljs:134" ],
|
||||
"translations" : {
|
||||
"en" : "Sitemap",
|
||||
"fr" : "Plan du site"
|
||||
|
|
|
@ -150,3 +150,12 @@
|
|||
(rx/catch (fn [err]
|
||||
(on-error)
|
||||
(rx/empty)))))))
|
||||
|
||||
;; --- Create Demo Profile
|
||||
|
||||
(def create-demo-profile
|
||||
(ptk/reify ::create-demo-profile
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/mutation :create-demo-profile {})
|
||||
(rx/map login)))))
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
[:strong "DO NOT USE"] " for real work, "
|
||||
" the projects will be periodicaly wiped."]])
|
||||
|
||||
|
||||
(mf/defc login-form
|
||||
[]
|
||||
(let [{:keys [data] :as form} (fm/use-form ::login-form {})]
|
||||
|
@ -61,7 +60,7 @@
|
|||
:class (fm/error-class form :username)
|
||||
:on-blur (fm/on-input-blur form :username)
|
||||
:on-change (fm/on-input-change form :username)
|
||||
:placeholder (tr "auth.email-or-username")
|
||||
:placeholder (tr "login.email-or-username")
|
||||
:type "text"}]
|
||||
[:input.input-text
|
||||
{:name "password"
|
||||
|
@ -70,23 +69,27 @@
|
|||
:class (fm/error-class form :password)
|
||||
:on-blur (fm/on-input-blur form :password)
|
||||
:on-change (fm/on-input-change form :password)
|
||||
:placeholder (tr "auth.password")
|
||||
:placeholder (tr "login.password")
|
||||
:type "password"}]
|
||||
[:input.btn-primary
|
||||
{:name "login"
|
||||
:tab-index "4"
|
||||
:class (when-not (:valid form) "btn-disabled")
|
||||
:disabled (not (:valid form))
|
||||
:value (tr "auth.signin")
|
||||
:value (tr "login.submit")
|
||||
:type "submit"}]
|
||||
|
||||
[:div.login-links
|
||||
[:a {:on-click #(st/emit! (rt/nav :profile-recovery-request))
|
||||
:tab-index "5"}
|
||||
(tr "auth.forgot-password")]
|
||||
(tr "login.forgot-password")]
|
||||
[:a {:on-click #(st/emit! (rt/nav :profile-register))
|
||||
:tab-index "6"}
|
||||
(tr "auth.no-account")]]]]))
|
||||
(tr "login.register")]
|
||||
[:a {:on-click #(st/emit! da/create-demo-profile)
|
||||
:tab-index "7"
|
||||
:title (tr "login.create-demo-profile-description")}
|
||||
(tr "login.create-demo-profile")]]]]))
|
||||
|
||||
(mf/defc login-page
|
||||
[]
|
||||
|
|
Loading…
Add table
Reference in a new issue