Host switching
This commit is contained in:
parent
31ffadbae3
commit
1a08acdc7c
@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<Navbar :user="user" />
|
<Navbar v-model:server="server" :user="user" />
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<Login :secret="secret" v-model:client="client" v-model:server="server" v-model:user="user" />
|
||||||
<router-view v-if="user"></router-view>
|
<router-view v-if="user"></router-view>
|
||||||
<Login :secret="secret" v-model:client="client" v-model:user="user" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -26,6 +26,7 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
client: null,
|
client: null,
|
||||||
|
server: null,
|
||||||
user: null,
|
user: null,
|
||||||
heartbeat: null,
|
heartbeat: null,
|
||||||
banner: '',
|
banner: '',
|
||||||
@ -36,7 +37,7 @@
|
|||||||
store: () => store
|
store: () => store
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
async client(value) {
|
async client(value, oldvalue) {
|
||||||
if(this.heartbeat) window.clearInterval(this.heartbeat);
|
if(this.heartbeat) window.clearInterval(this.heartbeat);
|
||||||
else {
|
else {
|
||||||
[
|
[
|
||||||
@ -47,7 +48,8 @@
|
|||||||
].forEach(route => this.$root.$router.addRoute(route));
|
].forEach(route => this.$root.$router.addRoute(route));
|
||||||
await this.$root.$router.replace(this.$route);
|
await this.$root.$router.replace(this.$route);
|
||||||
}
|
}
|
||||||
this.heartbeat = await value.heartbeat();
|
if(value) this.heartbeat = await value.heartbeat();
|
||||||
|
if(oldvalue) this.$router.go(); // refresh if changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
110
htdocs/Login.vue
110
htdocs/Login.vue
@ -1,25 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="card mb-3 shadow">
|
<div class="accordion mb-3 shadow">
|
||||||
<div class="card-header"><template v-if="user">{{user[2]}}</template><template v-else>Login</template></div>
|
<div class="accordion-item">
|
||||||
<div class="card-body">
|
<h2 class="accordion-header"><button class="accordion-button" :class="{ testing: (x_server) && (x_server.production != '1') }" type="button" @click="() => show = !show"><template v-if="user">{{user[2]}}<template v-if="server"> @ {{server.domain}}</template></template><template v-else>Login</template></button></h2>
|
||||||
<p class="card-text row"><code class="col" v-if="banner"><pre>{{banner.join('\n')}}</pre></code><code class="col" v-if="user"><pre>{{user.join('\n')}}</pre></code></p>
|
<div class="accordion-collapse collapse" :class="{ show }">
|
||||||
</div>
|
<div class="accordion-body">
|
||||||
<div class="input-group flex-nowrap" v-if="!user">
|
<div class="card">
|
||||||
<span class="input-group-text">🔑</span>
|
<div class="card-body">
|
||||||
<input type="password" class="form-control" placeholder="Access Code" v-model="accesscode" />
|
<p class="card-text row"><code class="col" v-if="banner"><pre>{{banner.join('\n')}}</pre></code><code class="col" v-if="user"><pre>{{user.join('\n')}}</pre></code></p>
|
||||||
<input type="password" class="form-control" placeholder="Verify Code" v-model="verifycode" />
|
</div>
|
||||||
<button class="btn btn-primary" type="button" v-on:click="submit">Login<template v-if="!(accesscode || verifycode)"> (omit AV codes for SAML)</template></button>
|
<button class="btn btn-danger" style="width: 100%;" type="button" v-if="user" v-on:click="logout">Logout</button>
|
||||||
|
<div class="input-group flex-nowrap" v-if="!user">
|
||||||
|
<span class="input-group-text">🔑</span>
|
||||||
|
<select class="form-control" v-model="host">
|
||||||
|
<option value="vista.bronx.med.va.gov:19201">Bronx BRX</option>
|
||||||
|
<option value="test.bronx.med.va.gov:19001">Bronx BRX-TEST</option>
|
||||||
|
<option value="vista.east-orange.med.va.gov:19203">East Orange NJH</option>
|
||||||
|
<option value="test.east-orange.med.va.gov:19003">East Orange NJH-TEST</option>
|
||||||
|
<option value="vista.hudson-valley.med.va.gov:19205">Hudson Valley NVH</option>
|
||||||
|
<option value="test.hudson-valley.med.va.gov:19005">Hudson Valley NVH-TEST</option>
|
||||||
|
<option value="vista.brooklyn.med.va.gov:19208">NY Harbor NYH</option>
|
||||||
|
<option value="test.brooklyn.med.va.gov:19008">NY Harbor NYH-TEST</option>
|
||||||
|
<option value="vista.northport.med.va.gov:19209">Northport NOP</option>
|
||||||
|
<option value="test.northport.med.va.gov:19009">Northport NOP-TEST</option>
|
||||||
|
<option value="vista.v02.med.va.gov:19224">VISN 2 V02</option>
|
||||||
|
<option value="test.v02.med.va.gov:19024">VISN 2 V02-TEST</option>
|
||||||
|
</select>
|
||||||
|
<input type="password" class="form-control" placeholder="Access Code" v-model="accesscode" />
|
||||||
|
<input type="password" class="form-control" placeholder="Verify Code" v-model="verifycode" />
|
||||||
|
<button class="btn btn-primary" type="button" v-on:click="login">Login<template v-if="!(accesscode || verifycode)"> (omit AV codes for SAML)</template></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.accordion-button.testing:not(.collapsed) {
|
||||||
|
color: #e40c63;
|
||||||
|
background-color: #ffe7f1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import cookie from './cookie.mjs';
|
||||||
import vistax from './vistax.mjs';
|
import vistax from './vistax.mjs';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
secret: String,
|
secret: String,
|
||||||
client: Object,
|
client: Object,
|
||||||
|
server: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
user: {
|
user: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: null
|
default: null
|
||||||
@ -27,6 +62,10 @@
|
|||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
'update:client': Object,
|
'update:client': Object,
|
||||||
|
'update:server': {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
'update:user': {
|
'update:user': {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: null
|
default: null
|
||||||
@ -34,7 +73,10 @@
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
show: false,
|
||||||
|
host: cookie.get('host'),
|
||||||
x_client: this.client,
|
x_client: this.client,
|
||||||
|
x_server: this.server,
|
||||||
x_user: this.user,
|
x_user: this.user,
|
||||||
banner: null,
|
banner: null,
|
||||||
accesscode: null,
|
accesscode: null,
|
||||||
@ -42,33 +84,57 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
host(value) {
|
||||||
|
cookie.set('host', value);
|
||||||
|
this.logout();
|
||||||
|
},
|
||||||
client(value) { this.x_client = value; },
|
client(value) { this.x_client = value; },
|
||||||
x_client(value) { this.$emit('update:client', value); },
|
x_client(value) { this.$emit('update:client', value); },
|
||||||
|
server(value) { this.x_server = value; },
|
||||||
|
x_server(value) { this.$emit('update:server', value); },
|
||||||
user(value) { this.x_user = value; },
|
user(value) { this.x_user = value; },
|
||||||
x_user(value) { this.$emit('update:user', value); }
|
x_user(value) { this.$emit('update:user', value); }
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
this.x_client = await vistax.Client.fromCookie(this.secret);
|
this.connect();
|
||||||
this.banner = await this.x_client.XUS_INTRO_MSG();
|
|
||||||
if((await this.x_client.userinfo()).result) try {
|
|
||||||
var user = await this.x_client.XUS_GET_USER_INFO();
|
|
||||||
this.x_user = user[0] ? user : null
|
|
||||||
} catch(ex) {
|
|
||||||
this.x_user = null;
|
|
||||||
}
|
|
||||||
this.$emit('update:user', this.x_user);
|
|
||||||
console.log('Backend secret', this.secret);
|
|
||||||
console.log(this.banner);
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async submit(evt) {
|
async connect() {
|
||||||
|
if(this.x_client) return this.x_client;
|
||||||
|
this.x_client = await vistax.Client.fromCookie(this.secret);
|
||||||
|
this.banner = await this.x_client.XUS_INTRO_MSG();
|
||||||
|
if((await this.x_client.userinfo()).result) try {
|
||||||
|
var user = await this.x_client.XUS_GET_USER_INFO();
|
||||||
|
this.x_user = user[0] ? user : null
|
||||||
|
} catch(ex) {
|
||||||
|
this.x_user = null;
|
||||||
|
}
|
||||||
|
this.$emit('update:user', this.x_user);
|
||||||
|
this.show = !this.x_user;
|
||||||
|
this.$emit('update:server', this.x_server = (await this.x_client.serverinfo()).result);
|
||||||
|
console.log('Backend secret', this.secret);
|
||||||
|
console.log(this.banner);
|
||||||
|
return this.x_client;
|
||||||
|
},
|
||||||
|
async login(evt) {
|
||||||
|
if(!this.x_client) await this.connect();
|
||||||
var res = await ((this.accesscode && this.verifycode) ? this.x_client.authenticate(this.accesscode + ';' + this.verifycode) : this.x_client.authenticate());
|
var res = await ((this.accesscode && this.verifycode) ? this.x_client.authenticate(this.accesscode + ';' + this.verifycode) : this.x_client.authenticate());
|
||||||
if(!!res.result[0]) {
|
if(!!res.result[0]) {
|
||||||
var user = await this.x_client.XUS_GET_USER_INFO();
|
var user = await this.x_client.XUS_GET_USER_INFO();
|
||||||
this.x_user = user[0] ? user : null
|
this.x_user = user[0] ? user : null
|
||||||
} else this.x_user = null;
|
} else this.x_user = null;
|
||||||
this.$emit('update:user', this.x_user);
|
this.$emit('update:user', this.x_user);
|
||||||
|
this.show = !this.x_user;
|
||||||
|
this.$emit('update:server', this.x_server = (await this.x_client.serverinfo()).result);
|
||||||
console.log('Authenticate', res);
|
console.log('Authenticate', res);
|
||||||
|
},
|
||||||
|
async logout(evt) {
|
||||||
|
if(this.x_client) {
|
||||||
|
console.log('Close', await this.x_client.close());
|
||||||
|
this.$emit('update:client', this.x_client = null);
|
||||||
|
this.$emit('update:server', this.x_server = null);
|
||||||
|
this.$emit('update:user', this.x_user = null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<router-link class="nav-link" to="/recall">Recall</router-link>
|
<router-link class="nav-link" to="/recall">Recall</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" v-if="user">
|
<li class="nav-item" v-if="server">
|
||||||
<a class="nav-link disabled">{{user[3]}}</a>
|
<a class="nav-link disabled">{{server.domain}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<form class="d-flex" role="search">
|
<form class="d-flex" role="search">
|
||||||
@ -34,6 +34,10 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
server: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
user: {
|
user: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: null
|
default: null
|
||||||
|
@ -6,6 +6,14 @@ export async function connect(secret, host='vista.northport.med.va.gov', port=19
|
|||||||
})).json();
|
})).json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function close(cid) {
|
||||||
|
return await (await fetch('/v1/vista/' + cid + '/close', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ id: Date.now() })
|
||||||
|
})).json();
|
||||||
|
}
|
||||||
|
|
||||||
export async function call(cid, method, ...params) {
|
export async function call(cid, method, ...params) {
|
||||||
return await (await fetch('/v1/vista/' + cid, {
|
return await (await fetch('/v1/vista/' + cid, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -47,5 +55,5 @@ export async function authenticate(cid, avcode=null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default window.vista = {
|
export default window.vista = {
|
||||||
connect, call, callctx, serverinfo, userinfo, authenticate
|
connect, close, call, callctx, serverinfo, userinfo, authenticate
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,8 @@ import vista from './vista.mjs';
|
|||||||
import cookie from './cookie.mjs';
|
import cookie from './cookie.mjs';
|
||||||
import { lab_parse, lab_reparse_results, measurement_parse } from './reportparser.mjs';
|
import { lab_parse, lab_reparse_results, measurement_parse } from './reportparser.mjs';
|
||||||
|
|
||||||
|
const COOKIE_TIME = 45;
|
||||||
|
|
||||||
function RPCError(type, ...args) {
|
function RPCError(type, ...args) {
|
||||||
this.name = type;
|
this.name = type;
|
||||||
this.message = args;
|
this.message = args;
|
||||||
@ -75,6 +77,10 @@ export function Client(cid, secret) {
|
|||||||
this.secret = secret;
|
this.secret = secret;
|
||||||
this.cid = cid;
|
this.cid = cid;
|
||||||
|
|
||||||
|
this.close = function() {
|
||||||
|
if(heartbeat) window.clearInterval(heartbeat);
|
||||||
|
return vista.close(cid);
|
||||||
|
};
|
||||||
this.call = (method, ...params) => vista.call(cid, method, ...params);
|
this.call = (method, ...params) => vista.call(cid, method, ...params);
|
||||||
this.callctx = (context, method, ...params) => vista.callctx(cid, context, method, ...params);
|
this.callctx = (context, method, ...params) => vista.callctx(cid, context, method, ...params);
|
||||||
this.heartbeat = async function(interval=null) {
|
this.heartbeat = async function(interval=null) {
|
||||||
@ -124,13 +130,16 @@ Client.fromScratch = async function(secret, host='vista.northport.med.va.gov', p
|
|||||||
if(data.result) return Client.fromID(data.result, secret);
|
if(data.result) return Client.fromID(data.result, secret);
|
||||||
};
|
};
|
||||||
|
|
||||||
Client.fromCookie = async function(secret, host='vista.northport.med.va.gov', port=19209) {
|
Client.fromCookie = async function(secret, defaulthost='vista.northport.med.va.gov:19209') {
|
||||||
if(!secret) secret = cookie.get('secret');
|
if(!secret) secret = cookie.get('secret');
|
||||||
if(secret) {
|
if(secret) {
|
||||||
|
var host = cookie.get('host');
|
||||||
|
host = (host || defaulthost).split(':');
|
||||||
if(secret != cookie.get('secret')) {
|
if(secret != cookie.get('secret')) {
|
||||||
console.log('Using new secret', secret);
|
console.log('Using new secret', secret);
|
||||||
var client = await Client.fromScratch(secret, host, port);
|
var client = await Client.fromScratch(secret, host[0], host[1]);
|
||||||
if(client) {
|
if(client) {
|
||||||
|
cookie.set('host', host.join(':'), COOKIE_TIME);
|
||||||
cookie.set('secret', secret);
|
cookie.set('secret', secret);
|
||||||
cookie.set('cid', client.cid);
|
cookie.set('cid', client.cid);
|
||||||
console.log('Established connection', client.cid);
|
console.log('Established connection', client.cid);
|
||||||
@ -143,8 +152,9 @@ Client.fromCookie = async function(secret, host='vista.northport.med.va.gov', po
|
|||||||
}
|
}
|
||||||
} else if(!cookie.get('cid')) {
|
} else if(!cookie.get('cid')) {
|
||||||
console.log('Using saved secret', secret);
|
console.log('Using saved secret', secret);
|
||||||
var client = await Client.fromScratch(secret, host, port);
|
var client = await Client.fromScratch(secret, host[0], host[1]);
|
||||||
if(client) {
|
if(client) {
|
||||||
|
cookie.set('host', host.join(':'), COOKIE_TIME);
|
||||||
cookie.set('secret', secret);
|
cookie.set('secret', secret);
|
||||||
cookie.set('cid', client.cid);
|
cookie.set('cid', client.cid);
|
||||||
console.log('Established connection', client.cid);
|
console.log('Established connection', client.cid);
|
||||||
@ -161,11 +171,13 @@ Client.fromCookie = async function(secret, host='vista.northport.med.va.gov', po
|
|||||||
var client = Client.fromID(cid, secret);
|
var client = Client.fromID(cid, secret);
|
||||||
if((await vista.call(cid, 'XWB_IM_HERE')).result == '1') {
|
if((await vista.call(cid, 'XWB_IM_HERE')).result == '1') {
|
||||||
var server = await client.serverinfo();
|
var server = await client.serverinfo();
|
||||||
if((host == server.result.host) && (port == server.result.port)) return client;
|
if((host[0] == server.result.host) && (host[1] == server.result.port)) {
|
||||||
else console.log('Rejecting previous connection to different server', server);
|
cookie.set('host', host.join(':'), COOKIE_TIME);
|
||||||
|
return client;
|
||||||
|
} else console.log('Rejecting previous connection to different server', server);
|
||||||
}
|
}
|
||||||
cookie.reset('cid');
|
cookie.reset('cid');
|
||||||
return await Client.fromCookie(secret, host, port);
|
return await Client.fromCookie(secret, host.join(':'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
11
main.py
11
main.py
@ -62,6 +62,17 @@ def application():
|
|||||||
else:
|
else:
|
||||||
return jsonify({ 'result': None, 'error': { 'type': 'Unauthorized', 'args': [] }, 'id': request.json.get('id') })
|
return jsonify({ 'result': None, 'error': { 'type': 'Unauthorized', 'args': [] }, 'id': request.json.get('id') })
|
||||||
|
|
||||||
|
@app.post('/v1/vista/<cid>/close')
|
||||||
|
def cb_close(cid):
|
||||||
|
try:
|
||||||
|
client = clients[cid]
|
||||||
|
res = client.close()
|
||||||
|
del clients[cid]
|
||||||
|
return jsonify({ 'result': res, 'error': None, 'id': request.json.get('id') })
|
||||||
|
except Exception as ex:
|
||||||
|
logger.exception(request.url)
|
||||||
|
return jsonify({ 'result': None, 'error': { 'type': ex.__class__.__name__, 'args': ex.args }, 'id': request.json.get('id') })
|
||||||
|
|
||||||
@app.post('/v1/vista/<cid>/serverinfo')
|
@app.post('/v1/vista/<cid>/serverinfo')
|
||||||
def cb_serverinfo(cid):
|
def cb_serverinfo(cid):
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user