瀏覽代碼

Account management

isundil 1 年之前
父節點
當前提交
0519e77b17
共有 6 個文件被更改,包括 113 次插入22 次删除
  1. 3 1
      model/mediaService.js
  2. 8 9
      router/api.js
  3. 5 5
      src/security.js
  4. 9 0
      static/public/css/style.css
  5. 84 3
      static/public/js/uiAccess.js
  6. 4 4
      templates/_login.js

+ 3 - 1
model/mediaService.js

@@ -28,7 +28,9 @@ MediaStruct.prototype.pushTag = function(tag) {
 MediaStruct.prototype.HaveAccess = function(accessList) {
     if (!fs.existsSync(this.path))
         return false;
-    // FIXME
+    accessList = accessList || {};
+    for (let i in accessList) {
+    }
     return true;
 }
 

+ 8 - 9
router/api.js

@@ -8,20 +8,19 @@ const MediaService = require('../model/mediaService.js');
 module.exports = { register: app => {
     app.router.get("/api/access/list", (req, res) => {
         app.routerUtils.onApiRequest(req, res);
-        app.routerUtils.jsonResponse(res, req.accessList || []);
+        app.routerUtils.jsonResponse(res, req.sessionObj?.accessList || {});
     });
     app.router.post("/api/access/link", async (req, res) => { // /api/access/link, post: { linkId: string }
         app.routerUtils.onApiRequest(req, res);
         if (!req.post?.linkId?.length)
             return app.routerUtils.httpResponse(res, 400, "Missing argument");
         let access = Security.addLinkToSession(req, req.post.linkId);
-        app.routerUtils.jsonResponse(res, access);
+        app.routerUtils.jsonResponse(res, req.sessionObj.accessList);
     });
     app.router.del("/api/access/:id", (req, res) => {
         app.routerUtils.onApiRequest(req, res);
-        Security.removeFromSession(req, req.params.id);
-        let access = Security.getAccessList(req.cookies);
-        app.routerUtils.jsonResponse(res, access);
+        const result = Security.removeFromSession(req, req.params.id);
+        app.routerUtils.jsonResponse(res, result);
     });
     app.router.get("/api/media/list", async (req, res) => {
         app.routerUtils.onApiRequest(req, res);
@@ -39,21 +38,21 @@ module.exports = { register: app => {
                 app,
                 isNaN(fromDate) ? 0 : fromDate,
                 isNaN(count) ? 25 : Math.min(75, count),
-                req.accessList),
+                req.sessionObj?.accessList),
             first: first,
             last: last
         });
     });
     app.router.get("/api/media/:md5sum", async (req, res) => {
         app.routerUtils.onApiRequest(req, res);
-        let data = await MediaService.fetchOne(app, req.params.md5sum, req.accessList);
+        let data = await MediaService.fetchOne(app, req.params.md5sum, req.sessionObj?.accessList);
         if (!data)
             return app.routerUtils.onPageNotFound(res);
         app.routerUtils.jsonResponse(res, data);
     });
     app.router.get("/api/media/thumbnail/:md5sum.jpg", async (req, res) => {
         app.routerUtils.onApiRequest(req, res);
-        let data = await MediaService.fetchOne(app, req.params.md5sum, req.accessList);
+        let data = await MediaService.fetchOne(app, req.params.md5sum, req.sessionObj?.accessList);
         if (!data)
             return app.routerUtils.onPageNotFound(res);
         try {
@@ -79,7 +78,7 @@ module.exports = { register: app => {
     });
     app.router.get("/api/media/original/:md5sum", async (req, res) => {
         app.routerUtils.onApiRequest(req, res);
-        let data = await MediaService.fetchOne(app, req.params.md5sum, req.accessList);
+        let data = await MediaService.fetchOne(app, req.params.md5sum, req.sessionObj?.accessList);
         if (!data)
             return app.routerUtils.onPageNotFound(res);
         const fileName = Path.basename(data.path);

+ 5 - 5
src/security.js

@@ -39,18 +39,18 @@ module.exports.createSession = req => {
     sessionInfos.sessionId = sessionKey;
     module.exports.pushSession(sessionKey, sessionInfos);
     req.cookies[module.exports.SESSION_COOKIE] = sessionKey;
-    return { key: sessionKey, accessList: sessionInfos.data.accessList };
+    return { key: sessionKey, data: sessionInfos.data };
 };
 module.exports.addLinkToSession = (req, linkId) => {
-    let session = getSessionObj(req.cookies);
+    let session = module.exports.getSessionObj(req.cookies);
     if (!session)
         return;
-    let accessList = new LinkAccess(linkId);
-    session.accessList[accessList.id()] = accessList;
+    let accessItem = new LinkAccess(linkId);
+    session.accessList[accessItem.id()] = accessItem;
     return session.accessList;
 };
 module.exports.removeFromSession = (req, accessId) => {
-    let session = getSessionObj(req.cookies);
+    let session = module.exports.getSessionObj(req.cookies);
     if (!session)
         return;
     delete session.accessList[accessId];

+ 9 - 0
static/public/css/style.css

@@ -3,6 +3,10 @@
     right: 0;
 }
 
+#pch-navbar #accessListMenu .accessItem .logout {
+    float: right;
+}
+
 #pch-page {
     margin-top: 6rem;
     padding: 1em 3em;
@@ -126,6 +130,11 @@
     right: 0;
     background: rgba(0, 0, 0, 0.7);
     z-index: 20;
+    display: none;
+}
+
+body.login-visible .login-wrapper {
+    display: initial;
 }
 
 .login-wrapper .modal {

+ 84 - 3
static/public/js/uiAccess.js

@@ -6,12 +6,74 @@ document.getElementById("menu-login").addEventListener("click", e => {
     document.body.classList.add("login-visible")
 });
 
+function closeLoginPopin() {
+    document.body.classList.remove("login-visible");
+    let inputFields = document.querySelectorAll(".login-wrapper .input-group input");
+    for (let i =0; i < inputFields.length; ++i)
+        inputFields[i].value = "";
+}
+
+document.querySelector(".login-wrapper .modal-footer button").addEventListener("click", () => closeLoginPopin());
+
+let loginUserPass = document.getElementById("login-userpass");
+let loginCode = document.getElementById("login-code");
+
+loginUserPass.querySelector("button").addEventListener("click", () => {
+    let user = loginUserPass.querySelector("input[type='text']").value;
+    let pass = loginUserPass.querySelector("input[type='password']").value;
+    console.log([user, pass]);
+});
+
+loginCode.querySelector("button").addEventListener("click", () => {
+    let code = loginCode.querySelector("input").value;
+    if (!code)
+        return;
+    LoadingTasks.push(() => {
+        return new Promise(ok => {
+            $.ajax({
+                url: "/api/access/link",
+                type: "POST",
+                data: { linkId: code },
+                success: data => {
+                    window.ReloadAccessList(data);
+                    closeLoginPopin();
+                    ok();
+                },
+                error: err => ok(false),
+            });
+        });
+    });
+});
+
+function logout(accessId) {
+    LoadingTasks.push(() => {
+        return new Promise(ok => {
+            $.ajax({
+                url: `/api/access/${accessId}`,
+                type: "DELETE",
+                success: data => {
+                    window.ReloadAccessList(data);
+                    closeLoginPopin();
+                    ok();
+                },
+                error: err => ok(false),
+            });
+        });
+    });
+}
+
 window.ReloadAccessList = function(accessList) {
+    let getIconForType = type => {
+        if (!!type.linkId) return "bi-link-45deg";
+        if (!!type.userName) return "bi-person";
+        return "bi-question-octagon";
+    }
+
     let rootNode = document.getElementById("accessListMenu");
     let items = rootNode.querySelectorAll("li.accessItem");
     for (let i =0; i < items.length; ++i)
         items[i].remove();
-    if (accessList.length) {
+    if (Object.keys(accessList||{}).length) {
         let li = document.createElement("li");
         li.classList.add("accessItem");
         li.classList.add("divider");
@@ -20,13 +82,32 @@ window.ReloadAccessList = function(accessList) {
         li.appendChild(hr);
         rootNode.appendChild(li);
     }
-    for (let i of accessList) {
+    for (let i in accessList) {
+        const accessTextValue = accessList[i].linkId;
+
         let li = document.createElement("li");
         li.classList.add("accessItem");
+        li.classList.add("dropdown-item");
         let a = document.createElement("a");
-        a.innerText = i.name;
+        let typeIcon = document.createElement("span");
+        typeIcon.innerHTML = "&nbsp;";
+        typeIcon.classList = 'type bi '+getIconForType(accessList[i]);
+        let accessText = document.createElement("span");
+        accessText.innerText = accessTextValue;
+        let logoutIcon = document.createElement("span");
+        logoutIcon.innerHTML = "&nbsp;";
+        logoutIcon.classList = 'logout bi bi-box-arrow-right'
+        a.appendChild(typeIcon);
+        a.appendChild(accessText);
+        a.appendChild(logoutIcon);
         li.appendChild(a);
         rootNode.appendChild(li);
+        a.addEventListener("click", e => {
+            e.preventDefault();
+            if (!window.confirm("Logout account " +accessTextValue +" ?"))
+                return;
+            logout(i);
+        });
     }
 }
 

+ 4 - 4
templates/_login.js

@@ -9,8 +9,8 @@ module.exports = `
                 </div>
                 <div class="modal-body">
                     <h6>Using Account</h6>
-                    <div class="input-group">
-                        <input class="form-control" type="text" placeholder="email  |  pseudo" />
+                    <div class="input-group" id="login-userpass">
+                        <input class="form-control" type="text" placeholder="User" />
                         <input class="form-control" type="password" placeholder="xxxxxx" />
                         <button type="button" class="btn btn-primary" data-dismiss="modal">Login</button>
                     </div>
@@ -18,12 +18,12 @@ module.exports = `
                 <hr/>
                 <div class="modal-body">
                     <h6>Using Link</h6>
-                    <div class="input-group">
+                    <div class="input-group" id="login-code">
                         <input class="form-control" type="text" placeholder="Invite Code" />
                         <button type="button" class="btn btn-primary" data-dismiss="modal">Checkout</button>
                     </div>
                 </div>
-                <div class="modal-footer"
+                <div class="modal-footer">
                     <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                 </div>
             </div>