From 6487be4812bb33bfc919df4ef48cbbf5689c839c Mon Sep 17 00:00:00 2001
From: zachmann <gabriel.zachmann@kit.edu>
Date: Fri, 12 Aug 2022 07:28:49 +0200
Subject: [PATCH] tokeninfo; transfercode

---
 internal/server/web/partials/scripts.mustache |  1 +
 .../server/web/partials/tokeninfo.mustache    | 53 ++++++++++++++++++-
 .../web/static/css/mytoken-loggedin.css       |  5 ++
 internal/server/web/static/js/discovery.js    |  1 +
 .../server/web/static/js/tokeninfo-status.js  |  3 ++
 internal/server/web/static/js/tokeninfo.js    | 21 +++++++-
 internal/server/web/static/js/transfercode.js | 20 +++++++
 7 files changed, 102 insertions(+), 2 deletions(-)
 create mode 100644 internal/server/web/static/js/transfercode.js

diff --git a/internal/server/web/partials/scripts.mustache b/internal/server/web/partials/scripts.mustache
index 595ca0d6..6def5819 100644
--- a/internal/server/web/partials/scripts.mustache
+++ b/internal/server/web/partials/scripts.mustache
@@ -17,6 +17,7 @@
         <script src="/static/js/mt-helper.js"></script>
         <script src="/static/js/home.js"></script>
         <script src="/static/js/create-at.js"></script>
+        <script src="/static/js/transfercode.js"></script>
         <script src="/static/js/tokeninfo.js"></script>
         <script type="module" src="/static/js/tokeninfo-status.js"></script>
         <script src="/static/js/lib/behave.min.js"></script>
diff --git a/internal/server/web/partials/tokeninfo.mustache b/internal/server/web/partials/tokeninfo.mustache
index f485db8f..177f0d9d 100644
--- a/internal/server/web/partials/tokeninfo.mustache
+++ b/internal/server/web/partials/tokeninfo.mustache
@@ -49,7 +49,10 @@
                     style="position: relative; left: -40px;">
                 <i class="far fa-copy"></i>
             </button>
-            <button type="button" class="btn btn-light ml-n4" id="create-tc">Create Transfercode</button>
+            <button type="button" class="btn btn-light ml-n4" id="create-tc" data-toggle="tooltip" data-placement="top"
+                    title="Click to create a Transfercode that can be used to easily transfer a mytoken to
+                    another device.">Create Transfercode
+            </button>
         </div>
     </div>
 
@@ -142,4 +145,52 @@
             <p class="card-text" id="tree-msg"></p>
         </div>
     </div>
+
+
+    <div class="modal fade" tabindex="-1" role="dialog" id="tc-modal">
+        <div class="modal-dialog modal-dialog-centered" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h4 class="modal-title">Your Transfercode</h4>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <p>
+                        You can use the following transfer code on any device until <span id="tc-expires"></span> to
+                        obtain the token on that device. This transfer code can only be used once.
+                    </p>
+
+                    <button class="btn btn-copy-inline copier" id="tc-copy" data-toggle="tooltip"
+                            data-placement="bottom" title="Copy to clipboard" data-clipboard-target="#tc-result">
+                        <i class="far fa-copy"></i>
+                    </button>
+                    <h4 class="text-center insert-tc code" id="tc-result"></h4>
+                    <p>
+                        You can use the mytoken client with the following command line to obtain the mytoken:
+                    </p>
+                    <button class="btn btn-copy-inline copier" id="tc-copy" data-toggle="tooltip"
+                            data-placement="bottom" title="Copy to clipboard" data-clipboard-target="#tc-command">
+                        <i class="far fa-copy"></i>
+                    </button>
+                    <pre id="tc-command" class="code">mytoken MT --TC="<span class="insert-tc"></span>"</pre>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="modal fade" tabindex="-1" role="dialog" id="error-modal">
+        <div class="modal-dialog modal-dialog-centered" role="document">
+            <div class="modal-content bg-danger">
+                <div class="modal-header">
+                    <h5 class="modal-title">Error</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span>
+                    </button>
+                </div>
+                <div class="modal-body" id="error-modal-msg"></div>
+            </div>
+        </div>
+    </div>
 {{/tokeninfo}}
\ No newline at end of file
diff --git a/internal/server/web/static/css/mytoken-loggedin.css b/internal/server/web/static/css/mytoken-loggedin.css
index 712749c1..4dffe06b 100644
--- a/internal/server/web/static/css/mytoken-loggedin.css
+++ b/internal/server/web/static/css/mytoken-loggedin.css
@@ -34,6 +34,11 @@ span.user-agent i + i {
     right: -8px;
 }
 
+.btn-copy-inline {
+    position: absolute;
+    right: 8px;
+}
+
 #sshHostConfigCopy {
     margin-top: 0;
     right: 15px;
diff --git a/internal/server/web/static/js/discovery.js b/internal/server/web/static/js/discovery.js
index 2c143b02..d8eca976 100644
--- a/internal/server/web/static/js/discovery.js
+++ b/internal/server/web/static/js/discovery.js
@@ -4,6 +4,7 @@ const configElements = [
     "usersettings_endpoint",
     "revocation_endpoint",
     "tokeninfo_endpoint",
+    "token_transfer_endpoint",
     "providers_supported",
     "jwks_uri"
 ]
diff --git a/internal/server/web/static/js/tokeninfo-status.js b/internal/server/web/static/js/tokeninfo-status.js
index 3c7feb01..fd3fcab3 100644
--- a/internal/server/web/static/js/tokeninfo-status.js
+++ b/internal/server/web/static/js/tokeninfo-status.js
@@ -15,6 +15,7 @@ const $tokeninfoBadgeExpDate = $('#tokeninfo-token-exp-date');
 
 const $tokeninfoTypeBadges = $('.tokeninfo-token-type');
 
+
 async function update_tokeninfo() {
     let token = storagePop('tokeninfo_token', true);
     if (token === "") {
@@ -37,6 +38,7 @@ async function update_tokeninfo() {
     }
     let tokeninfoEndpoint = storageGet('tokeninfo_endpoint');
     let jwksUri = storageGet('jwks_uri');
+    transferEndpoint = "";
     try {
         payload = jose.decodeJwt(token);
         let mytokenIss = payload['iss'];
@@ -48,6 +50,7 @@ async function update_tokeninfo() {
             }).then(function (data) {
                 tokeninfoEndpoint = data['tokeninfo_endpoint'];
                 jwksUri = data['jwks_uri'];
+                transferEndpoint = data['token_transfer_endpoint'];
             }).catch(function (e) {
                 console.error(e);
             });
diff --git a/internal/server/web/static/js/tokeninfo.js b/internal/server/web/static/js/tokeninfo.js
index d4d1b2bf..20a754af 100644
--- a/internal/server/web/static/js/tokeninfo.js
+++ b/internal/server/web/static/js/tokeninfo.js
@@ -1,4 +1,6 @@
 const $tokenInput = $('#tokeninfo-token');
+const $errorModal = $('#error-modal');
+const $errorModalMsg = $('#error-modal-msg')
 
 function _tokeninfo(action, successFnc, errorFnc, token = undefined) {
     let data = {
@@ -239,4 +241,21 @@ function initTokeninfo(...next) {
     $(prefixId("nbf", tokeninfoPrefix)).datetimepicker("minDate", null);
     $(prefixId("exp", tokeninfoPrefix)).datetimepicker("minDate", null);
     doNext(...next);
-}
\ No newline at end of file
+}
+
+let transferEndpoint = "";
+$('#create-tc').on('click', function () {
+    createTransferCode($tokenInput.val(),
+        function (tc, expiresIn) {
+            let now = new Date();
+            let expiresAt = formatTime(now.setSeconds(now.getSeconds() + expiresIn) / 1000);
+            $('.insert-tc').text(tc);
+            $('#tc-expires').text(expiresAt);
+            $('#tc-modal').modal();
+        },
+        function (errMsg) {
+            $errorModalMsg.text(errMsg);
+            $errorModal.modal();
+        },
+        transferEndpoint);
+});
\ No newline at end of file
diff --git a/internal/server/web/static/js/transfercode.js b/internal/server/web/static/js/transfercode.js
new file mode 100644
index 00000000..048ebd8f
--- /dev/null
+++ b/internal/server/web/static/js/transfercode.js
@@ -0,0 +1,20 @@
+function createTransferCode(token, okCallback, errCallback, endpoint = "") {
+    let data = {'mytoken': token};
+    data = JSON.stringify(data);
+    if (endpoint === "") {
+        endpoint = storageGet('token_transfer_endpoint');
+    }
+    $.ajax({
+        type: "POST",
+        url: endpoint,
+        data: data,
+        success: function (data) {
+            okCallback(data['transfer_code'], data['expires_in']);
+        },
+        error: function (errRes) {
+            errCallback(getErrorMessage(errRes));
+        },
+        dataType: "json",
+        contentType: "application/json"
+    });
+}
\ No newline at end of file
-- 
GitLab