Merge pull request #120 from ttshivers/password
feat(password): add password field to create and join room pages
This commit is contained in:
commit
f2e1fee947
10
src/App.vue
10
src/App.vue
|
@ -253,10 +253,6 @@ export default {
|
|||
},
|
||||
|
||||
inviteUrl() {
|
||||
// TODO: investigate passwords and invites. Is there really a point of a password if the
|
||||
// invite link contains it?
|
||||
// One alternative is to prompt for a password always instead, but maybe we don't need
|
||||
// passwords at all
|
||||
if (this.GET_ROOM) {
|
||||
if (this.GET_CONFIG.autojoin) {
|
||||
// If autojoin, just link to main site
|
||||
|
@ -266,13 +262,13 @@ export default {
|
|||
const invitePart = this.$router.resolve({
|
||||
name: 'join',
|
||||
params: {
|
||||
...(this.GET_SERVER.length > 0 && { server: this.GET_SERVER }),
|
||||
room: this.GET_ROOM,
|
||||
password: this.GET_PASSWORD,
|
||||
...(this.GET_SERVER.length > 0 && { server: this.GET_SERVER }),
|
||||
},
|
||||
}).href;
|
||||
|
||||
return new URL(invitePart, window.location).toString();
|
||||
const currentUrl = new URL(window.location.pathname, window.location.origin);
|
||||
return new URL(invitePart, currentUrl).toString();
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
|
|
@ -36,7 +36,7 @@ export default new Router({
|
|||
},
|
||||
|
||||
{
|
||||
path: '/join/:server?/:room/:password?',
|
||||
path: '/join/:room/:server?',
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
redirectAfterAuth: true,
|
||||
|
|
|
@ -6,6 +6,7 @@ import { slPlayerClientId } from '@/player/constants';
|
|||
import {
|
||||
open, close, on, waitForEvent, isConnected, emit,
|
||||
} from '@/socket';
|
||||
import JoinError from '@/utils/joinerror';
|
||||
import notificationSound from '@/assets/sounds/notification_simple-01.wav';
|
||||
|
||||
const notificationAudio = new Audio(notificationSound);
|
||||
|
@ -33,7 +34,7 @@ export default {
|
|||
await dispatch('DISCONNECT_IF_CONNECTED');
|
||||
|
||||
const currentUrl = new URL(window.location.pathname, window.location.origin);
|
||||
const properBase = new URL(getters.GET_SERVER, currentUrl);
|
||||
const properBase = new URL(getters.GET_SERVER, currentUrl.toString());
|
||||
|
||||
const url = combineUrl('socket.io', properBase.toString());
|
||||
console.log('ESTABLISH_SOCKET_CONNECTION', url.toString());
|
||||
|
@ -78,7 +79,8 @@ export default {
|
|||
|
||||
const { success, error, ...rest } = await waitForEvent('joinResult');
|
||||
if (!success) {
|
||||
throw new Error(error);
|
||||
// Password was wrong
|
||||
throw new JoinError(true, error);
|
||||
}
|
||||
|
||||
return rest;
|
||||
|
|
|
@ -68,8 +68,15 @@ export default {
|
|||
console.log('Rejoining');
|
||||
await waitForEvent('slPing');
|
||||
commit('SET_SOCKET_ID', getId());
|
||||
await dispatch('JOIN_ROOM_AND_INIT');
|
||||
// TODO: EXAMINE THIS AND FIGURE OUT HOW TO SYNC
|
||||
|
||||
try {
|
||||
await dispatch('JOIN_ROOM_AND_INIT');
|
||||
} catch (e) {
|
||||
const message = `Error reconnecting: ${e.message}`;
|
||||
console.error(message);
|
||||
await dispatch('DISPLAY_NOTIFICATION', message, { root: true });
|
||||
await dispatch('NAVIGATE_HOME', null, { root: true });
|
||||
}
|
||||
},
|
||||
|
||||
HANDLE_SLPING: async (context, secret) => {
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
|
||||
class JoinError extends Error {
|
||||
constructor(passwordIncorrect, ...params) {
|
||||
// Pass remaining arguments (including vendor specific ones) to parent constructor
|
||||
super(...params);
|
||||
|
||||
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, JoinError);
|
||||
}
|
||||
|
||||
this.name = 'JoinError';
|
||||
// Custom debugging information
|
||||
this.passwordIncorrect = passwordIncorrect;
|
||||
}
|
||||
}
|
||||
|
||||
export default JoinError;
|
|
@ -44,11 +44,11 @@
|
|||
</v-alert>
|
||||
|
||||
<v-expansion-panels
|
||||
v-if="!GET_CONFIG.force_slplayer"
|
||||
multiple
|
||||
flat
|
||||
>
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel
|
||||
:readonly="GET_CONFIG.force_slplayer"
|
||||
>
|
||||
<v-expansion-panel-header>
|
||||
Player: {{ GET_CHOSEN_CLIENT.name }}
|
||||
</v-expansion-panel-header>
|
||||
|
@ -60,22 +60,40 @@
|
|||
/>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
|
||||
<v-container>
|
||||
<v-row no-gutters>
|
||||
<v-col
|
||||
cols="12"
|
||||
>
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-header>
|
||||
Room: {{ roomName }}
|
||||
</v-expansion-panel-header>
|
||||
|
||||
<v-expansion-panel-content>
|
||||
<v-text-field
|
||||
v-model="roomName"
|
||||
label="Room Name"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
|
||||
<v-card-actions>
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-header disable-icon-rotate>
|
||||
Password
|
||||
<template v-slot:actions>
|
||||
<v-icon>
|
||||
lock
|
||||
</v-icon>
|
||||
</template>
|
||||
</v-expansion-panel-header>
|
||||
|
||||
<v-expansion-panel-content>
|
||||
<v-text-field
|
||||
v-model="roomPassword"
|
||||
label="Room Password"
|
||||
/>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
|
||||
<v-card-actions class="mt-2">
|
||||
<v-btn
|
||||
color="primary"
|
||||
:disabled="!GET_SERVERS_HEALTH || Object.keys(GET_SERVERS_HEALTH).length === 0
|
||||
|
@ -102,6 +120,7 @@ import { mapActions, mapGetters } from 'vuex';
|
|||
import redirection from '@/mixins/redirection';
|
||||
import { slPlayerClientId } from '@/player/constants';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import JoinError from '@/utils/joinerror';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -120,6 +139,7 @@ export default {
|
|||
// Default true because default client is slplayer
|
||||
clientConnectable: true,
|
||||
roomName: uuidv4(),
|
||||
roomPassword: null,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -177,7 +197,7 @@ export default {
|
|||
await this.SET_AND_CONNECT_AND_JOIN_ROOM({
|
||||
server: this.GET_BEST_SERVER,
|
||||
room: this.roomName,
|
||||
password: null,
|
||||
password: this.roomPassword,
|
||||
});
|
||||
|
||||
if (this.$route.name === 'CreateRoom') {
|
||||
|
@ -188,8 +208,15 @@ export default {
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
this.DISCONNECT_IF_CONNECTED();
|
||||
console.error(e);
|
||||
this.error = e.message;
|
||||
|
||||
if (e instanceof JoinError) {
|
||||
this.error = 'Room already in use';
|
||||
this.roomName = uuidv4();
|
||||
} else {
|
||||
this.error = e.message;
|
||||
}
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
</v-alert>
|
||||
|
||||
<v-expansion-panels
|
||||
v-if="!GET_CONFIG.force_slplayer"
|
||||
:value="panels"
|
||||
multiple
|
||||
flat
|
||||
>
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel
|
||||
:readonly="GET_CONFIG.force_slplayer"
|
||||
>
|
||||
<v-expansion-panel-header>
|
||||
Player: {{ GET_CHOSEN_CLIENT.name }}
|
||||
</v-expansion-panel-header>
|
||||
|
@ -41,9 +42,46 @@
|
|||
/>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
|
||||
<v-expansion-panel
|
||||
:readonly="true"
|
||||
>
|
||||
<v-expansion-panel-header disable-icon-rotate>
|
||||
Room: {{ room }}
|
||||
<template v-slot:actions>
|
||||
<v-icon color="teal">
|
||||
done
|
||||
</v-icon>
|
||||
</template>
|
||||
</v-expansion-panel-header>
|
||||
</v-expansion-panel>
|
||||
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-header disable-icon-rotate>
|
||||
Password
|
||||
<template v-slot:actions>
|
||||
<v-icon>
|
||||
lock
|
||||
</v-icon>
|
||||
</template>
|
||||
</v-expansion-panel-header>
|
||||
|
||||
<v-expansion-panel-content>
|
||||
<v-form>
|
||||
<v-text-field
|
||||
v-model="password"
|
||||
name="password"
|
||||
type="password"
|
||||
:error="passwordNeeded"
|
||||
autocomplete="room-password"
|
||||
label="Password"
|
||||
/>
|
||||
</v-form>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
|
||||
<v-card-actions>
|
||||
<v-card-actions class="mt-2">
|
||||
<v-btn
|
||||
color="primary"
|
||||
:disabled="!clientConnectable"
|
||||
|
@ -62,6 +100,7 @@
|
|||
import { mapActions, mapGetters } from 'vuex';
|
||||
import redirection from '@/mixins/redirection';
|
||||
import { slPlayerClientId } from '@/player/constants';
|
||||
import JoinError from '@/utils/joinerror';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -73,19 +112,14 @@ export default {
|
|||
],
|
||||
|
||||
props: {
|
||||
server: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
|
||||
room: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
||||
password: {
|
||||
server: {
|
||||
type: String,
|
||||
default: null,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -97,6 +131,9 @@ export default {
|
|||
clientConnectable: true,
|
||||
|
||||
error: null,
|
||||
password: null,
|
||||
passwordNeeded: false,
|
||||
panels: [],
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -141,8 +178,14 @@ export default {
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
this.DISCONNECT_IF_CONNECTED();
|
||||
console.error(e);
|
||||
this.error = e.message;
|
||||
|
||||
if (e instanceof JoinError) {
|
||||
this.passwordNeeded = true;
|
||||
this.panels = [2];
|
||||
}
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
|
|
Loading…
Reference in New Issue