Merge branch 'prod' into develop
This commit is contained in:
commit
1876484590
33
client/src/components/CopyrightNotice.vue
Normal file
33
client/src/components/CopyrightNotice.vue
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<div class="copyright-notice__version" @click="openInfoModal">
|
||||||
|
v{{ config.version }}, © 2021-2023, Settel
|
||||||
|
</div>
|
||||||
|
<InfoModal v-if="showInfoModal" @close="closeInfoModal" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useRuntimeConfig } from '#app'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const config = useRuntimeConfig()
|
||||||
|
|
||||||
|
const showInfoModal = ref(false)
|
||||||
|
const openInfoModal = () => { showInfoModal.value = true }
|
||||||
|
const closeInfoModal = () => { showInfoModal.value = false }
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.copyright-notice {
|
||||||
|
&__version {
|
||||||
|
position: absolute;
|
||||||
|
right: 1em;
|
||||||
|
bottom: 0;
|
||||||
|
color: #606060;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #c0c0c0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -22,7 +22,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref, watch } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import { PlayerEdit } from '@/composables/engine.d'
|
import { PlayerEdit } from '@/composables/engine.d'
|
||||||
import type { Button } from '@/components/admin/PlayerModal'
|
import type { Button } from '@/components/admin/PlayerModal'
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { useRoundStore } from '@/stores/RoundStore'
|
|||||||
import useI18n from './useI18n'
|
import useI18n from './useI18n'
|
||||||
import { $fetch } from 'ohmyfetch'
|
import { $fetch } from 'ohmyfetch'
|
||||||
|
|
||||||
export type AllowRole = '' | 'player' | 'gamemaster' | 'admin'
|
export type AllowRole = '' | 'player' | 'gamemaster' | 'admin' | 'setup'
|
||||||
export type AllowRoles = Array<AllowRole>
|
export type AllowRoles = Array<AllowRole>
|
||||||
|
|
||||||
export interface useAuth {
|
export interface useAuth {
|
||||||
@ -25,8 +25,17 @@ export default (): useAuth => {
|
|||||||
user.setUserInfo(userInfo)
|
user.setUserInfo(userInfo)
|
||||||
useI18n({}).setLang(userInfo.lang)
|
useI18n({}).setLang(userInfo.lang)
|
||||||
if (allowRoles.indexOf(userInfo.role) >= 0 ) {
|
if (allowRoles.indexOf(userInfo.role) >= 0 ) {
|
||||||
|
// user is authenticated and authorized, let the user in
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// game is not initialized yet, needs setup
|
||||||
|
if (userInfo.role === 'setup') {
|
||||||
|
document.location.pathname = '/setup'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// user is authenticated but not authorized for this page
|
||||||
if (user.isAdmin) {
|
if (user.isAdmin) {
|
||||||
document.location.pathname = '/admin'
|
document.location.pathname = '/admin'
|
||||||
// can't use navigateTo() for it fails with DOMException if two consecutive redirects happen (at least in docker container)
|
// can't use navigateTo() for it fails with DOMException if two consecutive redirects happen (at least in docker container)
|
||||||
@ -35,6 +44,7 @@ export default (): useAuth => {
|
|||||||
document.location.pathname = '/play'
|
document.location.pathname = '/play'
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// user is not authenticated
|
||||||
if (allowRoles.indexOf('') == -1 ) {
|
if (allowRoles.indexOf('') == -1 ) {
|
||||||
document.location.pathname = '/'
|
document.location.pathname = '/'
|
||||||
}
|
}
|
||||||
|
@ -12,34 +12,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="page-index__space" />
|
<div class="page-index__space" />
|
||||||
</div>
|
</div>
|
||||||
<div class="page-index__copyright-notice" @click="openInfoModal">
|
<CopyrightNotice />
|
||||||
v{{ config.version }}, © 2021-2022, Settel
|
|
||||||
</div>
|
|
||||||
<InfoModal v-if="showInfoModal" @close="closeInfoModal" />
|
|
||||||
<CreateTeamDialog v-if="showCreateTeamDialog" @close="closeCreateTeamDialog" />
|
<CreateTeamDialog v-if="showCreateTeamDialog" @close="closeCreateTeamDialog" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRuntimeConfig, navigateTo } from '#app'
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import useAuth from '@/composables/useAuth'
|
import useAuth from '@/composables/useAuth'
|
||||||
import useI18n from '@/composables/useI18n'
|
import useI18n from '@/composables/useI18n'
|
||||||
|
import CopyrightNotice from '../components/CopyrightNotice.vue';
|
||||||
|
|
||||||
const { $t } = useI18n({
|
const { $t } = useI18n({
|
||||||
'create-team': { en: 'Create Team ...', de: 'Team erstellen ...' },
|
'create-team': { en: 'Create Team ...', de: 'Team erstellen ...' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const config = useRuntimeConfig()
|
|
||||||
|
|
||||||
await useAuth().authenticateAndLoadUserInfo([''])
|
await useAuth().authenticateAndLoadUserInfo([''])
|
||||||
|
|
||||||
const showCreateTeamDialog = ref(false)
|
const showCreateTeamDialog = ref(false)
|
||||||
const showInfoModal = ref(false)
|
|
||||||
const createTeam = () => { showCreateTeamDialog.value = true }
|
const createTeam = () => { showCreateTeamDialog.value = true }
|
||||||
const closeCreateTeamDialog = () => { showCreateTeamDialog.value = false }
|
const closeCreateTeamDialog = () => { showCreateTeamDialog.value = false }
|
||||||
const openInfoModal = () => { showInfoModal.value = true }
|
|
||||||
const closeInfoModal = () => { showInfoModal.value = false }
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -92,17 +84,5 @@ body {
|
|||||||
&__space {
|
&__space {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__copyright-notice {
|
|
||||||
position: absolute;
|
|
||||||
right: 1em;
|
|
||||||
bottom: 0;
|
|
||||||
color: #606060;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #c0c0c0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
79
client/src/pages/setup.vue
Normal file
79
client/src/pages/setup.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TitleBox />
|
||||||
|
<div class="page-setup__action-box">
|
||||||
|
<div class="page-setup__description">
|
||||||
|
<p>{{ $t('description-1') }}</p>
|
||||||
|
<p>{{ $t('description-2') }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="page-setup__button">
|
||||||
|
<Button @click="createAdminAccount">{{ $t('create admin user') }}</Button>
|
||||||
|
|
||||||
|
<ModalDialog v-if="showAdminAccountCreatedDialog" :no-close-button="true" @close="showAdminAccountCreatedDialog = false">
|
||||||
|
<div class="create-team-dialog__auth-message">{{ $t('pin') }}</div>
|
||||||
|
<div class="create-team-dialog__pin">{{ authcode }}</div>
|
||||||
|
<div class="create-team-dialog__auth-message">{{ $t('remember-and-log-in') }}</div>
|
||||||
|
</ModalDialog>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CopyrightNotice />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import useAuth from '@/composables/useAuth'
|
||||||
|
import useI18n from '@/composables/useI18n'
|
||||||
|
|
||||||
|
const { $t } = useI18n({
|
||||||
|
'create admin user': { en: 'create admin user', de: 'Admin-Benutzer anlegen' },
|
||||||
|
'description-1': {
|
||||||
|
en: 'Congratulation!',
|
||||||
|
de: 'Herzlichen Glückwunsch! '
|
||||||
|
},
|
||||||
|
'description-2': {
|
||||||
|
en: 'You\'ve successfully installed Know Your Teammates.',
|
||||||
|
de: 'Know Your Teammates wurde erfolgreich installiert.'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await useAuth().authenticateAndLoadUserInfo(['setup'])
|
||||||
|
|
||||||
|
const showAdminAccountCreatedDialog = ref(false)
|
||||||
|
const authcode = ref('000000')
|
||||||
|
const createAdminAccount = () => {
|
||||||
|
authcode.value = ''
|
||||||
|
for (var i = 0; i < 6; i++) {
|
||||||
|
authcode.value += '' + Math.floor(Math.floor(Math.random() * 10000) / 100) % 10
|
||||||
|
}
|
||||||
|
showAdminAccountCreatedDialog.value = true
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '~/assets/css/components';
|
||||||
|
|
||||||
|
.page-setup {
|
||||||
|
&__action-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 340px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
margin: 32px 0 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__button {
|
||||||
|
display: flex;
|
||||||
|
margin: 32px auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,7 +3,7 @@ import { defineStore } from 'pinia'
|
|||||||
export type Userinfo = {
|
export type Userinfo = {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
role: '' | 'player' | 'gamemaster' | 'admin'
|
role: '' | 'player' | 'gamemaster' | 'admin' | 'setup'
|
||||||
game: string
|
game: string
|
||||||
lang: 'de' | 'en'
|
lang: 'de' | 'en'
|
||||||
isCameo: string
|
isCameo: string
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"name":"Massive Demo","lang":"de","created":1651603106}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "12.2",
|
|
||||||
"source": "9c5a22d3-1e82-4bad-95a4-c9efb169ede0"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "1.1",
|
|
||||||
"source": "4b1c22b8-6fa1-4c9d-98d7-cbf498035074"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "11.2",
|
|
||||||
"source": "cede08c4-768a-4792-b92f-8df162a07307"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "4.1",
|
|
||||||
"source": "b190ebb1-86c0-4308-a6b6-bf34237c10f8"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Admin #1",
|
|
||||||
"source": "f30802dc-1c18-4169-99fe-04d1d8e7bd9e"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "7.2",
|
|
||||||
"source": "3945635e-c65a-4fb7-a46c-675ec53abebe"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "16.1",
|
|
||||||
"source": "49295e5b-0d0a-44ea-9bff-e74acaaa6dcf"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "3.2",
|
|
||||||
"source": "4fa78612-accd-491d-93e6-cca251ac0e5a"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "5.1",
|
|
||||||
"source": "3c60f533-676b-4464-8542-1f3e6fc49d13"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Admin #2",
|
|
||||||
"source": "f30802dc-1c18-4169-99fe-04d1d8e7bd9e"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "2.2",
|
|
||||||
"source": "da6fdb50-8773-40ce-889f-c6f565ca35e3"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "6.1",
|
|
||||||
"source": "38f508e0-b808-4d28-be5b-d2f5cb54fd69"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "4.2",
|
|
||||||
"source": "b190ebb1-86c0-4308-a6b6-bf34237c10f8"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "13.1",
|
|
||||||
"source": "233dd18b-cb0d-4f77-b0ee-248dc7fec65d"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "9.2",
|
|
||||||
"source": "f99ee1de-af5c-4d7e-a1f4-622ad0cd40ac"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "12.1",
|
|
||||||
"source": "9c5a22d3-1e82-4bad-95a4-c9efb169ede0"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "5.2",
|
|
||||||
"source": "3c60f533-676b-4464-8542-1f3e6fc49d13"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "9.1",
|
|
||||||
"source": "f99ee1de-af5c-4d7e-a1f4-622ad0cd40ac"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "8.2",
|
|
||||||
"source": "81cf1907-8566-4b03-a433-3f6ea9bf8c85"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "15.1",
|
|
||||||
"source": "4706f51a-c014-4e0a-99f7-866e98b19986"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "1.2",
|
|
||||||
"source": "4b1c22b8-6fa1-4c9d-98d7-cbf498035074"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "11.1",
|
|
||||||
"source": "cede08c4-768a-4792-b92f-8df162a07307"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "10.2",
|
|
||||||
"source": "8f688b3b-6e2f-4bf2-bdfa-03762f2c7b72"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "6.2",
|
|
||||||
"source": "38f508e0-b808-4d28-be5b-d2f5cb54fd69"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "13.2",
|
|
||||||
"source": "233dd18b-cb0d-4f77-b0ee-248dc7fec65d"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "8.1",
|
|
||||||
"source": "81cf1907-8566-4b03-a433-3f6ea9bf8c85"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "10.1",
|
|
||||||
"source": "8f688b3b-6e2f-4bf2-bdfa-03762f2c7b72"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "16.2",
|
|
||||||
"source": "49295e5b-0d0a-44ea-9bff-e74acaaa6dcf"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "14.2",
|
|
||||||
"source": "51c4c7cb-8382-4bef-ad2d-c457c5af12f2"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "2.1",
|
|
||||||
"source": "da6fdb50-8773-40ce-889f-c6f565ca35e3"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "14.1",
|
|
||||||
"source": "51c4c7cb-8382-4bef-ad2d-c457c5af12f2"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "3.1",
|
|
||||||
"source": "4fa78612-accd-491d-93e6-cca251ac0e5a"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "7.1",
|
|
||||||
"source": "3945635e-c65a-4fb7-a46c-675ec53abebe"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "15.2",
|
|
||||||
"source": "4706f51a-c014-4e0a-99f7-866e98b19986"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
{"name":"Bumsquatsch","lang":"de","created":1670881903}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Extra Bumsquatsch vom Oberadmin",
|
|
||||||
"source": "6ef8620b-2b5e-4749-821e-b0722b8d8117",
|
|
||||||
"created": 1670882004
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Bumsquatsch #2",
|
|
||||||
"source": "c5e0cbf4-1556-4488-93de-9367f84e5ce8",
|
|
||||||
"created": 1670881947
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Bumsquatsch #1",
|
|
||||||
"source": "c5e0cbf4-1556-4488-93de-9367f84e5ce8",
|
|
||||||
"created": 1670881943
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
{"name":"Team Hogwards","lang":"en","created":1650831066}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "I'm friends with spiders.",
|
|
||||||
"source": "23c93faa-ac5b-4e37-bf32-4276aba682bb"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "My first magic wand - an exclusive model from designer Thoronus Karpes — was a gift from my father.",
|
|
||||||
"source": "15c03b7c-729f-4202-a880-3bcc7214dad9"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "My stupid brothers frequently test their latest invention on me.",
|
|
||||||
"source": "bff68447-513c-4fa3-9224-fc59d83da81a"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Since first grade, I've been best in all subjects and courses without a single miss.",
|
|
||||||
"source": "99e1aa2e-6e37-43c7-809c-28f093e2ae81"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "My private collection has 4031 different potions.",
|
|
||||||
"source": "35ee06ca-82c7-4f23-9bb9-bd0943848b07"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
{"name":"Team Hogwards","lang":"de","created":1649841591}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Ich bin seit der ersten Klasse in allen Fächern Klassenbeste:r.",
|
|
||||||
"source": "de69fa89-2b55-4c78-8718-9084458ceada"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Meine Privatsammlung umfasst 4031 verschiedene Zaubertränke.",
|
|
||||||
"source": "c885c77f-bbc8-4547-a3b4-baac5a58e76e"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Meinen ersten Zauberstab — ein exklusives Modell von Edeldesigner Thoronus Karpes — hat mir mein Vater geschenkt.",
|
|
||||||
"source": "cf230e60-9e1e-4158-93eb-ca184e15a6af"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Ich bin mit Spinnen befreundet.",
|
|
||||||
"source": "47ff4d04-b403-468f-b152-72226762e373"
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"quote": "Meine blöden Brüder testen ständig ihre neusten Erfindungen an mir.",
|
|
||||||
"source": "fae6e837-d603-436d-ba0c-df6a850350c0"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Draco","role":"player","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831166,"lastLoggedIn":0}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"805088","name":"Player #13","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603645,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Hagrid","role":"player","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831162,"lastLoggedIn":0}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Snape","role":"player","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831158,"lastLoggedIn":0}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"406234","name":"Player #06","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603311,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"098577","name":"Player #07","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603340,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"044843","name":"Player #05","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603278,"lastLoggedIn":1651603989}
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"authcode": "646162",
|
|
||||||
"name": "Settel (Admin)",
|
|
||||||
"role": "admin"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"606242","name":"Player #15","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603679,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Hagrid","role":"player","game":"e24444aa-8a18-48aa-a36d-8f84620726f8","created":1649841804}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"920510","name":"Player #16","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603703,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"350736","name":"Player #01","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603175,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"160658","name":"Player #03","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603237,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"529733","name":"Player #14","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603656,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"171903","name":"Admin von Bumsquatsch","role":"gamemaster","game":"652e36de-99c4-4365-b557-8fd189a396ab","created":1670881903,"lastLoggedIn":1670881992}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"776678","name":"Player #08","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603395,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"837254","name":"Player #10","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603471,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Hermine","role":"player","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831149,"lastLoggedIn":0}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"370173","name":"Player #12","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603619,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"934289","name":"Harry","role":"player","game":"e24444aa-8a18-48aa-a36d-8f84620726f8","created":1649841804}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"001002","name":"Dumbledore","role":"gamemaster","game":"e24444aa-8a18-48aa-a36d-8f84620726f8","created":1649841804,"lastLoggedIn":1649841540}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"576653","name":"Player #04","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603258,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Ron","role":"player","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831153,"lastLoggedIn":0}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"000000","name":"Harald von Bumsquatsch","role":"player","game":"652e36de-99c4-4365-b557-8fd189a396ab","created":1670881923,"lastLoggedIn":1670881950}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Snape","role":"player","game":"e24444aa-8a18-48aa-a36d-8f84620726f8","created":1649841804}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"019048","name":"Player #11","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603541,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Draco","role":"player","game":"e24444aa-8a18-48aa-a36d-8f84620726f8","created":1649841804}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"123456","name":"Harry","role":"player","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831122,"lastLoggedIn":1661949675}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"256473","name":"Player #02","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603188,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Hermine","role":"player","game":"e24444aa-8a18-48aa-a36d-8f84620726f8","created":1649841804}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"002002","name":"Dumbledore","role":"gamemaster","game":"663576f0-1378-496b-a970-578bdcb222af","created":1650831066,"lastLoggedIn":1661965111}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"631854","name":"Admin","role":"gamemaster","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603106,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"494434","name":"Player #09","role":"player","game":"64efba47-87dc-4c19-851c-aa68c9f0e2c1","created":1651603452,"lastLoggedIn":1651603989}
|
|
@ -1 +0,0 @@
|
|||||||
{"authcode":"","name":"Ron","role":"player","game":"e24444aa-8a18-48aa-a36d-8f84620726f8","created":1649841804}
|
|
8
server/src/application/isInitialized.go
Normal file
8
server/src/application/isInitialized.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package application
|
||||||
|
|
||||||
|
func (app *Application) IsInitialized() bool {
|
||||||
|
app.mu.Lock()
|
||||||
|
defer app.mu.Unlock()
|
||||||
|
|
||||||
|
return len(app.users) > 0
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package application
|
package application
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
@ -11,9 +12,16 @@ func (app *Application) loadGames() error {
|
|||||||
dirName := path.Join(app.config.DataDir, "games")
|
dirName := path.Join(app.config.DataDir, "games")
|
||||||
files, err := os.ReadDir(dirName)
|
files, err := os.ReadDir(dirName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = os.Mkdir(dirName, 0777); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
id := file.Name()
|
id := file.Name()
|
||||||
gameDirName := path.Join(dirName, id)
|
gameDirName := path.Join(dirName, id)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package application
|
package application
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
@ -11,9 +12,16 @@ func (app *Application) loadUsers() error {
|
|||||||
dirName := path.Join(app.config.DataDir, "users")
|
dirName := path.Join(app.config.DataDir, "users")
|
||||||
files, err := os.ReadDir(dirName)
|
files, err := os.ReadDir(dirName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = os.Mkdir(dirName, 0777); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
app.mu.Lock()
|
app.mu.Lock()
|
||||||
defer app.mu.Unlock()
|
defer app.mu.Unlock()
|
||||||
|
|
||||||
|
@ -17,3 +17,7 @@ type Application struct {
|
|||||||
playerATime map[string]time.Time
|
playerATime map[string]time.Time
|
||||||
debounceMap map[string]bool
|
debounceMap map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ServerInfo struct {
|
||||||
|
IsInitialized bool `json:"isInitialized"`
|
||||||
|
}
|
||||||
|
@ -8,24 +8,26 @@ import (
|
|||||||
|
|
||||||
type ApplicationConfig struct {
|
type ApplicationConfig struct {
|
||||||
DataDir string
|
DataDir string
|
||||||
|
BindString string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApplicationConfig() ApplicationConfig {
|
func NewApplicationConfig() ApplicationConfig {
|
||||||
|
flagVerbosePtr := flag.Bool("v", false, "log debug messages, too")
|
||||||
flagVerbose := flag.Bool("v", false, "log debug messages, too")
|
flagQuietPtr := flag.Bool("q", false, "be quiet; warning and error messages only")
|
||||||
flagQuiet := flag.Bool("q", false, "be quiet; warning and error messages only")
|
bindStringPtr := flag.String("b", "localhost:32039", "interface and port to bind to")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
log.SetLoglevel(log.LOG_INFO)
|
log.SetLoglevel(log.LOG_INFO)
|
||||||
|
|
||||||
if *flagVerbose {
|
if *flagVerbosePtr {
|
||||||
log.SetLoglevel(log.LOG_DEBUG)
|
log.SetLoglevel(log.LOG_DEBUG)
|
||||||
}
|
}
|
||||||
if *flagQuiet {
|
if *flagQuietPtr {
|
||||||
log.SetLoglevel(log.LOG_WARN)
|
log.SetLoglevel(log.LOG_WARN)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ApplicationConfig{
|
return ApplicationConfig{
|
||||||
DataDir: "data/",
|
DataDir: "data/",
|
||||||
|
BindString: *bindStringPtr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package handler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"sirlab.de/go/knowyt/application"
|
"sirlab.de/go/knowyt/application"
|
||||||
"sirlab.de/go/knowyt/user"
|
"sirlab.de/go/knowyt/user"
|
||||||
)
|
)
|
||||||
@ -11,21 +13,32 @@ type PrivateHandlerFunc func(*user.User, http.ResponseWriter, *http.Request)
|
|||||||
|
|
||||||
type AuthMux struct {
|
type AuthMux struct {
|
||||||
mux *http.ServeMux
|
mux *http.ServeMux
|
||||||
Port int
|
bindInterfaceAndPort string
|
||||||
app *application.Application
|
app *application.Application
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthMux(app *application.Application) *AuthMux {
|
func NewAuthMux(app *application.Application) *AuthMux {
|
||||||
|
bindString := app.GetConfig().BindString
|
||||||
|
if !strings.Contains(bindString, ":") {
|
||||||
|
bindString = bindString + ":32039"
|
||||||
|
}
|
||||||
mux := AuthMux{
|
mux := AuthMux{
|
||||||
app: app,
|
app: app,
|
||||||
mux: http.NewServeMux(),
|
mux: http.NewServeMux(),
|
||||||
Port: 32039,
|
bindInterfaceAndPort: bindString,
|
||||||
}
|
}
|
||||||
http.Handle("/", mux.mux)
|
http.Handle("/", mux.mux)
|
||||||
|
|
||||||
return &mux
|
return &mux
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (authMux *AuthMux) GetBindString() string {
|
||||||
|
if authMux.bindInterfaceAndPort[0] == ':' {
|
||||||
|
return "*" + authMux.bindInterfaceAndPort
|
||||||
|
}
|
||||||
|
return authMux.bindInterfaceAndPort
|
||||||
|
}
|
||||||
|
|
||||||
func (authMux *AuthMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (authMux *AuthMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
authMux.mux.ServeHTTP(w, r)
|
authMux.mux.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
@ -39,5 +52,5 @@ func (authMux *AuthMux) PublicHandle(pattern string, handler http.Handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (authMux *AuthMux) ListenAndServe() {
|
func (authMux *AuthMux) ListenAndServe() {
|
||||||
http.ListenAndServe(":32039", nil)
|
http.ListenAndServe(authMux.bindInterfaceAndPort, nil)
|
||||||
}
|
}
|
||||||
|
25
server/src/handler/checkSetup.go
Normal file
25
server/src/handler/checkSetup.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"sirlab.de/go/knowyt/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (authMux *AuthMux) CheckSetup(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !authMux.app.IsInitialized() {
|
||||||
|
usrSetup := UserInfoJson{
|
||||||
|
Name: "setup",
|
||||||
|
Role: user.ROLE_SETUP,
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
jsonString, _ := json.Marshal(usrSetup)
|
||||||
|
fmt.Fprintf(w, "%s", string(jsonString))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
authMux.accessDenied(w, r)
|
||||||
|
}
|
@ -8,18 +8,22 @@ import (
|
|||||||
"sirlab.de/go/knowyt/user"
|
"sirlab.de/go/knowyt/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (authMux *AuthMux) PrivateHandleFunc(pattern string, handlerFunc PrivateHandlerFunc) {
|
func (authMux *AuthMux) PrivateOrPublicHandleFunc(pattern string, privateHandlerFunc PrivateHandlerFunc, publicHandlerFunc HandlerFunc) {
|
||||||
authMux.mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
authMux.mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||||
usr, err := authMux.getUserFromSession(r)
|
usr, err := authMux.getUserFromSession(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
authMux.accessDenied(w, r)
|
// could not authenticate
|
||||||
return
|
publicHandlerFunc(w, r)
|
||||||
|
} else {
|
||||||
|
privateHandlerFunc(usr, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
handlerFunc(usr, w, r)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (authMux *AuthMux) PrivateHandleFunc(pattern string, handlerFunc PrivateHandlerFunc) {
|
||||||
|
authMux.PrivateOrPublicHandleFunc(pattern, handlerFunc, authMux.accessDenied)
|
||||||
|
}
|
||||||
|
|
||||||
func (authMux *AuthMux) accessDenied(w http.ResponseWriter, r *http.Request) {
|
func (authMux *AuthMux) accessDenied(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusForbidden)
|
w.WriteHeader(http.StatusForbidden)
|
||||||
fmt.Fprintf(w, "Forbidden")
|
fmt.Fprintf(w, "Forbidden")
|
||||||
|
@ -22,8 +22,8 @@ func main() {
|
|||||||
mux.PublicHandleFunc("/api/login", mux.Login)
|
mux.PublicHandleFunc("/api/login", mux.Login)
|
||||||
mux.PublicHandleFunc("/api/logout", mux.Logout)
|
mux.PublicHandleFunc("/api/logout", mux.Logout)
|
||||||
mux.PublicHandleFunc("/api/createGame", app.CreateGame)
|
mux.PublicHandleFunc("/api/createGame", app.CreateGame)
|
||||||
|
mux.PrivateOrPublicHandleFunc("/api/userinfo", mux.GetUserInfo, mux.CheckSetup)
|
||||||
mux.PrivateHandleFunc("/api/cameo", mux.Cameo)
|
mux.PrivateHandleFunc("/api/cameo", mux.Cameo)
|
||||||
mux.PrivateHandleFunc("/api/userinfo", mux.GetUserInfo)
|
|
||||||
mux.PrivateHandleFunc("/api/gameinfo", app.GetGameInfo)
|
mux.PrivateHandleFunc("/api/gameinfo", app.GetGameInfo)
|
||||||
mux.PrivateHandleFunc("/api/games", app.GetGames)
|
mux.PrivateHandleFunc("/api/games", app.GetGames)
|
||||||
mux.PrivateHandleFunc("/api/setGameName", app.SetGameName)
|
mux.PrivateHandleFunc("/api/setGameName", app.SetGameName)
|
||||||
@ -47,6 +47,6 @@ func main() {
|
|||||||
mux.PublicHandleFunc("/", handler.FileHandler)
|
mux.PublicHandleFunc("/", handler.FileHandler)
|
||||||
|
|
||||||
// start listening
|
// start listening
|
||||||
log.Info("Listening at http://localhost:%d/\n", mux.Port)
|
log.Info("Listening at http://%s/\n", mux.GetBindString())
|
||||||
mux.ListenAndServe()
|
mux.ListenAndServe()
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user