Make registration RESTful
parent
6821447c74
commit
afba73e1e8
|
@ -18,6 +18,7 @@ export type { PlayerSchema } from './models/PlayerSchema';
|
|||
export type { PlayerTeamAvailabilityRoleSchema } from './models/PlayerTeamAvailabilityRoleSchema';
|
||||
export type { PutScheduleForm } from './models/PutScheduleForm';
|
||||
export type { RoleSchema } from './models/RoleSchema';
|
||||
export type { SetUsernameJson } from './models/SetUsernameJson';
|
||||
export type { TeamInviteSchema } from './models/TeamInviteSchema';
|
||||
export type { TeamInviteSchemaList } from './models/TeamInviteSchemaList';
|
||||
export { TeamRole } from './models/TeamRole';
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
export type CreateTeamJson = {
|
||||
discordWebhookUrl?: string;
|
||||
leagueTimezone: string;
|
||||
minuteOffset?: number;
|
||||
teamName: string;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/* generated using openapi-typescript-codegen -- do not edit */
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type SetUsernameJson = {
|
||||
username: string;
|
||||
};
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export type TeamSchema = {
|
||||
discordWebhookUrl?: string;
|
||||
createdAt: string;
|
||||
id: number;
|
||||
minuteOffset: number;
|
||||
teamName: string;
|
||||
|
|
|
@ -7,6 +7,7 @@ import type { CreateTeamJson } from '../models/CreateTeamJson';
|
|||
import type { EditMemberRolesJson } from '../models/EditMemberRolesJson';
|
||||
import type { PlayerSchema } from '../models/PlayerSchema';
|
||||
import type { PutScheduleForm } from '../models/PutScheduleForm';
|
||||
import type { SetUsernameJson } from '../models/SetUsernameJson';
|
||||
import type { TeamInviteSchema } from '../models/TeamInviteSchema';
|
||||
import type { TeamInviteSchemaList } from '../models/TeamInviteSchemaList';
|
||||
import type { ViewAvailablePlayersResponse } from '../models/ViewAvailablePlayersResponse';
|
||||
|
@ -455,4 +456,23 @@ export class DefaultService {
|
|||
},
|
||||
});
|
||||
}
|
||||
/**
|
||||
* set_username <POST>
|
||||
* @param requestBody
|
||||
* @returns PlayerSchema OK
|
||||
* @throws ApiError
|
||||
*/
|
||||
public setUsername(
|
||||
requestBody?: SetUsernameJson,
|
||||
): CancelablePromise<PlayerSchema> {
|
||||
return this.httpRequest.request({
|
||||
method: 'POST',
|
||||
url: '/api/user/username',
|
||||
body: requestBody,
|
||||
mediaType: 'application/json',
|
||||
errors: {
|
||||
422: `Unprocessable Entity`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,11 @@ const router = createRouter({
|
|||
{
|
||||
path: "/team/id/:id",
|
||||
name: "team-details",
|
||||
component: TeamDetailsView
|
||||
component: TeamDetailsView,
|
||||
//children: [
|
||||
// path: "members",
|
||||
// component:
|
||||
//],
|
||||
},
|
||||
]
|
||||
});
|
||||
|
@ -49,10 +53,12 @@ router
|
|||
const authStore = useAuthStore();
|
||||
console.log("test");
|
||||
if (!authStore.isLoggedIn && !authStore.hasCheckedAuth) {
|
||||
try {
|
||||
await authStore.getUser();
|
||||
} catch (exception) {
|
||||
if (to.name != "login") {
|
||||
try {
|
||||
await authStore.getUser();
|
||||
} catch (exception) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -46,6 +46,10 @@ export const useAuthStore = defineStore("auth", () => {
|
|||
});
|
||||
}
|
||||
|
||||
async function setUsername(username: string) {
|
||||
return client.default.setUsername({ username });
|
||||
}
|
||||
|
||||
return {
|
||||
steamId,
|
||||
username,
|
||||
|
@ -54,5 +58,6 @@ export const useAuthStore = defineStore("auth", () => {
|
|||
isRegistering,
|
||||
getUser,
|
||||
login,
|
||||
setUsername,
|
||||
}
|
||||
});
|
||||
|
|
|
@ -65,11 +65,11 @@ export const useTeamsStore = defineStore("teams", () => {
|
|||
);
|
||||
}
|
||||
|
||||
async function createTeam(teamName: string, tz: string, webhook?: string) {
|
||||
async function createTeam(teamName: string, tz: string, minuteOffset: number) {
|
||||
return await client.default.createTeam({
|
||||
teamName,
|
||||
leagueTimezone: tz,
|
||||
discordWebhookUrl: webhook,
|
||||
minuteOffset,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,48 +1,75 @@
|
|||
<script setup lang="ts">
|
||||
import { useAuthStore } from "../stores/auth";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const queryParams = route.query;
|
||||
const queryParams = computed(() => route.query);
|
||||
|
||||
const auth = useAuthStore();
|
||||
|
||||
const registerUsername = ref("");
|
||||
|
||||
function register() {
|
||||
const params = {
|
||||
...queryParams,
|
||||
username: registerUsername,
|
||||
}
|
||||
//const params = {
|
||||
// ...queryParams.value,
|
||||
// username: registerUsername.value,
|
||||
//};
|
||||
|
||||
auth.login(params)
|
||||
//auth.login(params)
|
||||
// .then(() => router.push("/"));
|
||||
auth.setUsername(registerUsername.value)
|
||||
.then(() => router.push("/"));
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (Object.keys(queryParams).length == 0) {
|
||||
auth.isRegistering = true;
|
||||
return;
|
||||
}
|
||||
|
||||
auth.login(queryParams)
|
||||
.then(() => router.push("/"));
|
||||
auth.login(queryParams.value)
|
||||
.then(() => {
|
||||
if (!auth.isRegistering) {
|
||||
router.push("/");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<main>
|
||||
<main>
|
||||
<div class="login-container">
|
||||
<template v-if="auth.isRegistering">
|
||||
<h1>Register</h1>
|
||||
<input v-model="registerUsername" />
|
||||
<button class="accent" type="submit">Register</button>
|
||||
<h1>New account</h1>
|
||||
<p>
|
||||
Your account has been newly created. Select a username to be
|
||||
associated with this account.
|
||||
</p>
|
||||
<div class="form-group margin">
|
||||
<h3>Username</h3>
|
||||
<input v-model="registerUsername" />
|
||||
</div>
|
||||
<div class="form-group margin">
|
||||
<div class="action-buttons">
|
||||
<button class="accent" type="submit" @click="register()">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else>
|
||||
Logging in...
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.login-container {
|
||||
align-items: center;
|
||||
max-width: 500px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 11pt;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -24,7 +24,7 @@ watch(minuteOffset, (newValue) => {
|
|||
const webhook = ref("");
|
||||
|
||||
function createTeam() {
|
||||
teams.createTeam(teamName.value, timezone.value, webhook.value)
|
||||
teams.createTeam(teamName.value, timezone.value, minuteOffset.value)
|
||||
.then(() => {
|
||||
router.push("/");
|
||||
});
|
||||
|
@ -64,7 +64,7 @@ function createTeam() {
|
|||
</div>
|
||||
</div>
|
||||
<em class="aside">
|
||||
Matches will be scheduled against {{ timezone }} at
|
||||
Matches will be scheduled based on {{ timezone }} at
|
||||
{{ minuteOffset }}
|
||||
<span v-if="minuteOffset == 1">
|
||||
minute
|
||||
|
@ -107,23 +107,6 @@ function createTeam() {
|
|||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.form-group.margin {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.form-group.row {
|
||||
flex-direction: row;
|
||||
margin: none;
|
||||
}
|
||||
|
||||
#minute-offset-group {
|
||||
flex-grow: unset;
|
||||
flex-shrink: 1;
|
||||
|
@ -135,9 +118,4 @@ input {
|
|||
width: 100%;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,6 +5,7 @@ import login
|
|||
import schedule
|
||||
import team
|
||||
from spec import spec
|
||||
import user
|
||||
|
||||
connect_db_with_app()
|
||||
|
||||
|
@ -12,6 +13,7 @@ api = Blueprint("api", __name__, url_prefix="/api")
|
|||
api.register_blueprint(login.api_login)
|
||||
api.register_blueprint(schedule.api_schedule)
|
||||
api.register_blueprint(team.api_team)
|
||||
api.register_blueprint(user.api_user)
|
||||
|
||||
@api.get("/debug/set-cookie")
|
||||
@api.post("/debug/set-cookie")
|
||||
|
|
|
@ -11,6 +11,7 @@ from app_db import db
|
|||
from models.auth_session import AuthSession
|
||||
from models.player import Player, PlayerSchema
|
||||
from middleware import requires_authentication
|
||||
import sys
|
||||
|
||||
api_login = Blueprint("login", __name__, url_prefix="/login")
|
||||
|
||||
|
@ -36,7 +37,14 @@ def get_user(player: Player, auth_session: AuthSession):
|
|||
def steam_authenticate():
|
||||
params = request.get_json()
|
||||
params["openid.mode"] = "check_authentication"
|
||||
response = requests.post(STEAM_OPENID_URL, data=params)
|
||||
|
||||
steam_params = params
|
||||
if "username" in steam_params:
|
||||
del steam_params["username"]
|
||||
|
||||
response = requests.post(STEAM_OPENID_URL, data=steam_params)
|
||||
print("response text = ", file=sys.stderr)
|
||||
print(response.text, file=sys.stderr)
|
||||
|
||||
# check if authentication was successful
|
||||
if "is_valid:true" in response.text:
|
||||
|
@ -50,19 +58,14 @@ def steam_authenticate():
|
|||
Player.steam_id == steam_id
|
||||
).one_or_none()
|
||||
|
||||
is_registering = False
|
||||
if not player:
|
||||
if "username" in params:
|
||||
# we are registering, so create user
|
||||
player = Player()
|
||||
player.username = params["username"]
|
||||
player.steam_id = steam_id
|
||||
else:
|
||||
# prompt client to resend with username field
|
||||
return make_response({
|
||||
"message": "Awaiting registration",
|
||||
"hint": "Resend the POST request with a username field",
|
||||
"isRegistering": True,
|
||||
})
|
||||
# we are registering, so create user
|
||||
player = Player()
|
||||
player.username = str(steam_id)
|
||||
player.steam_id = steam_id
|
||||
is_registering = True
|
||||
db.session.add(player)
|
||||
|
||||
auth_session = create_auth_session_for_player(player)
|
||||
|
||||
|
@ -70,6 +73,7 @@ def steam_authenticate():
|
|||
"message": "Logged in",
|
||||
"steamId": player.steam_id,
|
||||
"username": player.username,
|
||||
"isRegistering": is_registering,
|
||||
})
|
||||
|
||||
# TODO: secure=True in production
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
from flask import Blueprint
|
||||
from spectree import Response
|
||||
from middleware import requires_authentication
|
||||
from models.player import Player, PlayerSchema
|
||||
from spec import spec, BaseModel
|
||||
from app_db import db
|
||||
|
||||
|
||||
api_user = Blueprint("user", __name__, url_prefix="/user")
|
||||
|
||||
class SetUsernameJson(BaseModel):
|
||||
username: str
|
||||
|
||||
@api_user.post("username")
|
||||
@spec.validate(
|
||||
resp=Response(
|
||||
HTTP_200=PlayerSchema,
|
||||
),
|
||||
operation_id="set_username",
|
||||
)
|
||||
@requires_authentication
|
||||
def set_username(json: SetUsernameJson, player: Player, **kwargs):
|
||||
player.username = json.username
|
||||
db.session.commit()
|
||||
return PlayerSchema.from_model(player).dict(by_alias=True), 200
|
Loading…
Reference in New Issue