Port session list to vue.
This commit is contained in:
parent
111beb5f12
commit
5b17a2fbe4
55
client/components/Session.vue
Normal file
55
client/components/Session.vue
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<template>
|
||||||
|
<p>
|
||||||
|
<button
|
||||||
|
class="btn pull-right remove-session"
|
||||||
|
@click.prevent="signOut"
|
||||||
|
>
|
||||||
|
<template v-if="session.current">
|
||||||
|
Sign out
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
Revoke
|
||||||
|
</template>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<strong>{{ session.agent }}</strong>
|
||||||
|
|
||||||
|
<a
|
||||||
|
:href="'https://ipinfo.io/'+session.ip"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>{{ session.ip }}</a>
|
||||||
|
|
||||||
|
<template v-if="!session.current">
|
||||||
|
<br>
|
||||||
|
<template v-if="session.active">
|
||||||
|
<em>Currently active</em>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
Last used on <time>{{ session.lastUse | localetime }}</time>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const Auth = require("../js/auth");
|
||||||
|
const socket = require("../js/socket");
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Session",
|
||||||
|
props: {
|
||||||
|
session: Object,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
signOut() {
|
||||||
|
if (!this.session.current) {
|
||||||
|
socket.emit("sign-out", this.session.token);
|
||||||
|
} else {
|
||||||
|
socket.emit("sign-out");
|
||||||
|
Auth.signout();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -471,13 +471,29 @@
|
|||||||
class="session-list"
|
class="session-list"
|
||||||
>
|
>
|
||||||
<h2>Sessions</h2>
|
<h2>Sessions</h2>
|
||||||
<!-- TODO: Sessions -->
|
|
||||||
|
|
||||||
<h3>Current session</h3>
|
<h3>Current session</h3>
|
||||||
<div id="session-current" />
|
<div
|
||||||
|
v-if="$store.getters.currentSession"
|
||||||
|
id="session-current"
|
||||||
|
>
|
||||||
|
<Session :session="$store.getters.currentSession" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3>Other sessions</h3>
|
<h3>Other sessions</h3>
|
||||||
<div id="session-list" />
|
<div id="session-list">
|
||||||
|
<p v-if="$store.state.sessions.length == 0">Loading…</p>
|
||||||
|
<p v-else-if="$store.getters.otherSessions.length == 0">
|
||||||
|
<em>You are not currently logged in to any other device.</em>'
|
||||||
|
</p>
|
||||||
|
<template v-else>
|
||||||
|
<Session
|
||||||
|
v-for="session in $store.getters.otherSessions"
|
||||||
|
:key="session.token"
|
||||||
|
:session="session"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@ -488,11 +504,13 @@
|
|||||||
// const storage = require("../../js/localStorage"); // TODO: use this
|
// const storage = require("../../js/localStorage"); // TODO: use this
|
||||||
import socket from "../../js/socket";
|
import socket from "../../js/socket";
|
||||||
import RevealPassword from "../RevealPassword.vue";
|
import RevealPassword from "../RevealPassword.vue";
|
||||||
|
import Session from "../Session.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Settings",
|
name: "Settings",
|
||||||
components: {
|
components: {
|
||||||
RevealPassword,
|
RevealPassword,
|
||||||
|
Session,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -510,6 +528,8 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.options = require("../../js/options"); // TODO: do this in a smarter way
|
this.options = require("../../js/options"); // TODO: do this in a smarter way
|
||||||
|
|
||||||
|
socket.emit("sessions:get");
|
||||||
|
|
||||||
// Enable protocol handler registration if supported
|
// Enable protocol handler registration if supported
|
||||||
if (window.navigator.registerProtocolHandler) {
|
if (window.navigator.registerProtocolHandler) {
|
||||||
this.canRegisterProtocol = true;
|
this.canRegisterProtocol = true;
|
||||||
|
@ -559,6 +559,7 @@ kbd {
|
|||||||
display: none;
|
display: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 220px;
|
width: 220px;
|
||||||
|
max-height: 100%;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,11 +34,6 @@ socket.on("configuration", function(data) {
|
|||||||
|
|
||||||
vueApp.serverConfiguration = data;
|
vueApp.serverConfiguration = data;
|
||||||
|
|
||||||
$("#settings").on("show", () => {
|
|
||||||
$("#session-list").html("<p>Loading…</p>");
|
|
||||||
socket.emit("sessions:get");
|
|
||||||
});
|
|
||||||
|
|
||||||
if (data.fileUpload) {
|
if (data.fileUpload) {
|
||||||
upload.initialize(data.fileUploadMaxFileSize);
|
upload.initialize(data.fileUploadMaxFileSize);
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,8 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const $ = require("jquery");
|
|
||||||
const Auth = require("../auth");
|
|
||||||
const socket = require("../socket");
|
const socket = require("../socket");
|
||||||
const templates = require("../../views");
|
const {vueApp} = require("../vue");
|
||||||
|
|
||||||
socket.on("sessions:list", function(data) {
|
socket.on("sessions:list", function(data) {
|
||||||
data.sort((a, b) => b.lastUse - a.lastUse);
|
data.sort((a, b) => b.lastUse - a.lastUse);
|
||||||
|
vueApp.$store.commit("sessions", data);
|
||||||
let html = "";
|
|
||||||
data.forEach((connection) => {
|
|
||||||
if (connection.current) {
|
|
||||||
$("#session-current").html(templates.session(connection));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
html += templates.session(connection);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (html.length === 0) {
|
|
||||||
html = "<p><em>You are not currently logged in to any other device.</em></p>";
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#session-list").html(html);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#settings").on("click", ".remove-session", function() {
|
|
||||||
const token = $(this).data("token");
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
socket.emit("sign-out", token);
|
|
||||||
} else {
|
|
||||||
socket.emit("sign-out");
|
|
||||||
Auth.signout();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,7 @@ export default new Vuex.Store({
|
|||||||
isConnected: false,
|
isConnected: false,
|
||||||
isNotified: false,
|
isNotified: false,
|
||||||
activeWindow: null,
|
activeWindow: null,
|
||||||
|
sessions: [],
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
isConnected(state, payload) {
|
isConnected(state, payload) {
|
||||||
@ -22,5 +23,12 @@ export default new Vuex.Store({
|
|||||||
currentNetworkConfig(state, payload) {
|
currentNetworkConfig(state, payload) {
|
||||||
state.currentNetworkConfig = payload;
|
state.currentNetworkConfig = payload;
|
||||||
},
|
},
|
||||||
|
sessions(state, payload) {
|
||||||
|
state.sessions = payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
currentSession: (state) => state.sessions.find((item) => item.current),
|
||||||
|
otherSessions: (state) => state.sessions.filter((item) => !item.current),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
<p>
|
|
||||||
<button
|
|
||||||
class="btn pull-right remove-session"
|
|
||||||
{{#unless current}}data-token="{{token}}"{{/unless}}
|
|
||||||
>
|
|
||||||
{{#if current}}
|
|
||||||
Sign out
|
|
||||||
{{else}}
|
|
||||||
Revoke
|
|
||||||
{{/if}}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<strong>{{agent}}</strong>
|
|
||||||
|
|
||||||
<a href="https://ipinfo.io/{{ip}}" target="_blank" rel="noopener">{{ip}}</a>
|
|
||||||
|
|
||||||
{{#unless current}}
|
|
||||||
<br>
|
|
||||||
{{#if active}}
|
|
||||||
<em>Currently active</em>
|
|
||||||
{{else}}
|
|
||||||
Last used on <time>{{localetime lastUse}}</time>
|
|
||||||
{{/if}}
|
|
||||||
{{/unless}}
|
|
||||||
</p>
|
|
Loading…
Reference in New Issue
Block a user