0
Fork 0
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:
Andrey Antukh 2020-01-14 13:13:10 +01:00
parent b0ca6493e3
commit e42ccf932e
12 changed files with 285 additions and 199 deletions

View file

@ -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

View file

@ -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 (

View file

@ -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

View file

@ -77,7 +77,6 @@
(> user-index 0))
(create-additional-project-user conn [project-index user-index])))))
;; --- Create Page Files
(def create-file-sql

View file

@ -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))

View file

@ -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

View 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})))

View file

@ -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)))))))

View file

@ -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]

View file

@ -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"

View file

@ -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)))))

View file

@ -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
[]