mirror of
https://github.com/penpot/penpot.git
synced 2026-07-29 09:26:14 +00:00
✨ Add link to download a nitrate activation code request (#10900)
This commit is contained in:
parent
9f92206a1c
commit
70675919c7
@ -413,6 +413,17 @@
|
||||
(generate-nitrate-uri "api/connectivity")
|
||||
schema:connectivity params))
|
||||
|
||||
(def ^:private schema:identity
|
||||
[:map
|
||||
[:nitrate-id ::sm/text]
|
||||
[:public-key ::sm/text]])
|
||||
|
||||
(defn- get-identity-api
|
||||
[cfg params]
|
||||
(request-to-nitrate cfg :get
|
||||
(generate-nitrate-uri "api/identity")
|
||||
schema:identity params))
|
||||
|
||||
(def ^:private schema:redeem-result
|
||||
[:map
|
||||
[:cancel-at [:maybe schema:timestamp]]])
|
||||
@ -491,6 +502,7 @@
|
||||
:get-subscription (partial get-subscription-api cfg)
|
||||
:get-subscription-warning (partial get-subscription-warning-api cfg)
|
||||
:connectivity (partial get-connectivity-api cfg)
|
||||
:get-identity (partial get-identity-api cfg)
|
||||
:redeem-activation-code (partial redeem-activation-code-api cfg)}))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
[app.auth.oidc :as oidc]
|
||||
[app.common.data :as d]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.json :as json]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.time :as ct]
|
||||
[app.common.types.nitrate-permissions :as nitrate-perms]
|
||||
@ -24,7 +25,8 @@
|
||||
[app.rpc.nitrate.emails-helper :as neh]
|
||||
[app.rpc.nitrate.organization-helper :as noh]
|
||||
[app.rpc.notifications :as notifications]
|
||||
[app.util.services :as sv]))
|
||||
[app.util.services :as sv]
|
||||
[buddy.core.codecs :as bc]))
|
||||
|
||||
|
||||
(defn assert-is-owner [cfg profile-id team-id]
|
||||
@ -114,6 +116,35 @@
|
||||
:cause cause)
|
||||
(throw cause)))))))
|
||||
|
||||
(def ^:private activation-code-request-filename
|
||||
"penpot-activation-code-request.txt")
|
||||
|
||||
(sv/defmethod ::get-nitrate-activation-code-request
|
||||
"Returns a Base64-encoded JSON file requesting a Nitrate activation code.
|
||||
Payload includes nitrateId, publicKey, email and iat."
|
||||
{::rpc/auth true
|
||||
::doc/added "2.20"
|
||||
::sm/params [:map]
|
||||
::sm/result ::sm/text}
|
||||
[cfg {:keys [::rpc/profile-id]}]
|
||||
(let [profile (db/get cfg :profile {:id profile-id})
|
||||
nitrate-identity (nitrate/call cfg :get-identity {})]
|
||||
(when-not nitrate-identity
|
||||
(ex/raise :type :validation
|
||||
:code :nitrate-identity-unavailable
|
||||
:hint "Unable to retrieve nitrate identity"))
|
||||
(-> (json/encode {:nitrate-id (:nitrate-id nitrate-identity)
|
||||
:public-key (:public-key nitrate-identity)
|
||||
:email (:email profile)
|
||||
:iat (ct/seconds (ct/now))}
|
||||
:key-fn json/write-camel-key)
|
||||
(bc/str->bytes)
|
||||
(bc/bytes->b64-str)
|
||||
(rph/wrap)
|
||||
(rph/with-header "content-type" "text/plain")
|
||||
(rph/with-header "content-disposition"
|
||||
(str "attachment; filename=\"" activation-code-request-filename "\"")))))
|
||||
|
||||
(def ^:private sql:prefix-team-name-and-unset-default
|
||||
"UPDATE team
|
||||
SET name = ? || name,
|
||||
|
||||
@ -6,16 +6,20 @@
|
||||
|
||||
(ns backend-tests.rpc-nitrate-test
|
||||
(:require
|
||||
[app.common.json :as json]
|
||||
[app.common.time :as ct]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
[app.db :as-alias db]
|
||||
[app.email :as eml]
|
||||
[app.http :as-alias http]
|
||||
[app.nitrate :as nitrate]
|
||||
[app.rpc :as-alias rpc]
|
||||
[app.rpc.commands.nitrate]
|
||||
[app.rpc.commands.teams :as teams]
|
||||
[app.rpc.helpers :as rph]
|
||||
[backend-tests.helpers :as th]
|
||||
[buddy.core.codecs :as bc]
|
||||
[clojure.test :as t]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
@ -933,3 +937,44 @@
|
||||
:organization-id org-id})]
|
||||
(t/is (th/success? out))
|
||||
(t/is (empty? @sent))))))
|
||||
|
||||
(t/deftest get-nitrate-activation-code-request
|
||||
(let [profile (th/create-profile* 1 {:is-active true})
|
||||
nitrate-id "nitrate-instance-1"
|
||||
public-key "-----BEGIN PUBLIC KEY-----\nMIIB\n-----END PUBLIC KEY-----"
|
||||
now (ct/now)]
|
||||
(with-redefs [cf/flags (conj cf/flags :nitrate)
|
||||
ct/now (constantly now)
|
||||
nitrate/call (fn [_cfg method _params]
|
||||
(t/is (= :get-identity method))
|
||||
{:nitrate-id nitrate-id
|
||||
:public-key public-key})]
|
||||
(let [out (th/command! {::th/type :get-nitrate-activation-code-request
|
||||
::rpc/profile-id (:id profile)})
|
||||
body (-> (:result out)
|
||||
(bc/b64->str)
|
||||
(json/decode :key-fn json/read-kebab-key))]
|
||||
(t/is (th/success? out))
|
||||
(t/is (= {:nitrate-id nitrate-id
|
||||
:public-key public-key
|
||||
:email (:email profile)
|
||||
:iat (ct/seconds now)}
|
||||
body))
|
||||
|
||||
(let [[_ method-fn] (get-in th/*system* [:app.rpc/methods :get-nitrate-activation-code-request])
|
||||
result (method-fn {::rpc/profile-id (:id profile)
|
||||
::rpc/request-at now})
|
||||
headers (::http/headers (meta result))]
|
||||
(t/is (rph/wrapped? result))
|
||||
(t/is (= "text/plain" (get headers "content-type")))
|
||||
(t/is (= "attachment; filename=\"penpot-activation-code-request.txt\""
|
||||
(get headers "content-disposition"))))))))
|
||||
|
||||
(t/deftest get-nitrate-activation-code-request-identity-unavailable
|
||||
(let [profile (th/create-profile* 1 {:is-active true})]
|
||||
(with-redefs [cf/flags (conj cf/flags :nitrate)
|
||||
nitrate/call (fn [_cfg _method _params] nil)]
|
||||
(let [out (th/command! {::th/type :get-nitrate-activation-code-request
|
||||
::rpc/profile-id (:id profile)})]
|
||||
(t/is (not (th/success? out)))
|
||||
(t/is (th/ex-of-code? (:error out) :nitrate-identity-unavailable))))))
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
[app.main.ui.nitrate.nitrate-activation-success-modal]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.util.webapi :as wapi]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
@ -63,7 +64,16 @@
|
||||
(mf/deps on-accept)
|
||||
(fn [event]
|
||||
(when (and (= "Enter" (.-key event)) (.-ctrlKey event))
|
||||
(on-accept event))))]
|
||||
(on-accept event))))
|
||||
|
||||
on-download-request-click
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(->> (rp/cmd! :get-nitrate-activation-code-request {})
|
||||
(rx/subs!
|
||||
(fn [body]
|
||||
(->> (wapi/create-blob body "text/plain")
|
||||
(dom/trigger-download "penpot-activation-code-request.txt")))))))]
|
||||
|
||||
[:div {:class (stl/css :modal-overlay)}
|
||||
[:div {:class (stl/css :modal-dialog)}
|
||||
@ -101,7 +111,11 @@
|
||||
:value (tr "nitrate.code-activation.submit")
|
||||
:on-click on-accept}]]
|
||||
[:div {:class (stl/css :footer-text)}
|
||||
(tr "nitrate.code-activation.footer") " "
|
||||
(tr "nitrate.code-activation.footer-before")
|
||||
[:a {:class (stl/css :link)
|
||||
:on-click on-download-request-click}
|
||||
(tr "nitrate.code-activation.footer-link")]
|
||||
(tr "nitrate.code-activation.footer-after") " "
|
||||
[:a {:class (stl/css :link)
|
||||
:href "mailto:sales@nitrate.com"}
|
||||
"sales@nitrate.com"]]]]]))
|
||||
|
||||
@ -84,9 +84,9 @@
|
||||
(tr "nitrate.form.cancel-anytime")]]]
|
||||
|
||||
[:p {:class (stl/css :modal-text-medium)}
|
||||
(tr "nitrate.form.have-code") " " [:a {:class (stl/css :link)
|
||||
:on-click on-activate-click}
|
||||
(tr "nitrate.form.enter-code")]]
|
||||
(tr "nitrate.form.subscribe-with-code") " " [:a {:class (stl/css :link)
|
||||
:on-click on-activate-click}
|
||||
(tr "nitrate.form.enter-code")]]
|
||||
|
||||
[:p {:class (stl/css :modal-text-medium)}
|
||||
[:a {:class (stl/css :link) :href dnt/go-to-subscription-url}
|
||||
@ -102,7 +102,7 @@
|
||||
"sales@penpot.app"]]
|
||||
[:div {:class (stl/css :activation-code)}
|
||||
[:p {:class (stl/css :modal-text-large)}
|
||||
(tr "nitrate.form.have-code")]
|
||||
(tr "nitrate.form.subscribe-with-code")]
|
||||
[:p {:class (stl/css :modal-text-large)}
|
||||
[:a {:class (stl/css :link)
|
||||
:on-click on-activate-click}
|
||||
|
||||
@ -4372,8 +4372,14 @@ msgid "nitrate.modal-success.title"
|
||||
msgstr "Welcome to Enterprise!"
|
||||
|
||||
#: src/app/main/ui/nitrate/nitrate_code_activation_modal.cljs:104
|
||||
msgid "nitrate.code-activation.footer"
|
||||
msgstr "Need a code? Contact us:"
|
||||
msgid "nitrate.code-activation.footer-before"
|
||||
msgstr "Need a code? Download your "
|
||||
|
||||
msgid "nitrate.code-activation.footer-link"
|
||||
msgstr "activation code request"
|
||||
|
||||
msgid "nitrate.code-activation.footer-after"
|
||||
msgstr " and contact us:"
|
||||
|
||||
#: src/app/main/ui/nitrate/nitrate_code_activation_modal.cljs:86
|
||||
msgid "nitrate.code-activation.input-label"
|
||||
@ -4473,8 +4479,8 @@ msgid "nitrate.form.enterprise.price"
|
||||
msgstr "per member per month"
|
||||
|
||||
#: src/app/main/ui/nitrate/nitrate_form.cljs:80, src/app/main/ui/nitrate/nitrate_form.cljs:98
|
||||
msgid "nitrate.form.have-code"
|
||||
msgstr "Have an activation code?"
|
||||
msgid "nitrate.form.subscribe-with-code"
|
||||
msgstr "Subscribe with an activation code"
|
||||
|
||||
#: src/app/main/ui/nitrate/nitrate_form.cljs:86
|
||||
msgid "nitrate.form.see-plan"
|
||||
|
||||
@ -4247,8 +4247,14 @@ msgid "nitrate.modal-success.title"
|
||||
msgstr "¡Bienvenido a Enterprise!"
|
||||
|
||||
#: src/app/main/ui/nitrate/nitrate_code_activation_modal.cljs:104
|
||||
msgid "nitrate.code-activation.footer"
|
||||
msgstr "¿Necesitas un código? Contáctanos:"
|
||||
msgid "nitrate.code-activation.footer-before"
|
||||
msgstr "¿Necesitas un código? Descarga tu "
|
||||
|
||||
msgid "nitrate.code-activation.footer-link"
|
||||
msgstr "solicitud de código de activación"
|
||||
|
||||
msgid "nitrate.code-activation.footer-after"
|
||||
msgstr " y contáctanos:"
|
||||
|
||||
#: src/app/main/ui/nitrate/nitrate_code_activation_modal.cljs:86
|
||||
msgid "nitrate.code-activation.input-label"
|
||||
@ -4351,8 +4357,8 @@ msgid "nitrate.form.enterprise.price"
|
||||
msgstr "por miembro al mes"
|
||||
|
||||
#: src/app/main/ui/nitrate/nitrate_form.cljs:80, src/app/main/ui/nitrate/nitrate_form.cljs:98
|
||||
msgid "nitrate.form.have-code"
|
||||
msgstr "¿Tienes un código de activación?"
|
||||
msgid "nitrate.form.subscribe-with-code"
|
||||
msgstr "Suscribete con un código de activación"
|
||||
|
||||
#: src/app/main/ui/nitrate/nitrate_form.cljs:86
|
||||
msgid "nitrate.form.see-plan"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user