Fix saving profile and add generating new API key

This commit is contained in:
Paul Bienkowski 2021-11-30 23:32:42 +01:00
parent 2f375dc24d
commit 004ad46251
2 changed files with 55 additions and 16 deletions

View file

@ -1,6 +1,9 @@
import logging
import os
import binascii
from sanic.response import json
from sanic.exceptions import InvalidUsage
from obs.api.app import api, require_auth
@ -16,7 +19,7 @@ def user_to_json(user):
"bio": user.bio,
"image": user.image,
"areTracksVisibleForAll": user.are_tracks_visible_for_all,
# "apiKey": user.api_key,
"apiKey": user.api_key,
}
@ -29,13 +32,17 @@ async def get_user(req):
@require_auth
async def put_user(req):
user = req.ctx.user
data = req.json
for key in ["username", "email", "bio", "image"]:
if key in req.json and isinstance(req.json[key], (str, type(None))):
setattr(user, key, req.json[key])
for key in ["email", "bio", "image"]:
if key in data and isinstance(data[key], (str, type(None))):
setattr(user, key, data[key])
if "areTracksVisibleForAll" in req.json:
user.are_tracks_visible_for_all = bool(req.json["areTracksVisibleForAll"])
if "areTracksVisibleForAll" in data:
user.are_tracks_visible_for_all = bool(data["areTracksVisibleForAll"])
if data.get("updateApiKey"):
user.api_key = binascii.b2a_hex(os.urandom(16)).decode("ascii")
await req.ctx.db.commit()
return json(user_to_json(req.ctx.user))

View file

@ -19,8 +19,8 @@ const SettingsPage = connect((state) => ({login: state.login}), {setLogin})(func
setLoading(true)
setErrors(null)
try {
const response = await api.put('/user', {body: {user: changes}})
setLogin(response.user)
const response = await api.put('/user', {body: changes})
setLogin(response)
} catch (err) {
setErrors(err.errors)
} finally {
@ -30,6 +30,19 @@ const SettingsPage = connect((state) => ({login: state.login}), {setLogin})(func
[setLoading, setLogin, setErrors]
)
const onGenerateNewKey = React.useCallback(async () => {
setLoading(true)
setErrors(null)
try {
const response = await api.put('/user', {body: {updateApiKey: true}})
setLogin(response)
} catch (err) {
setErrors(err.errors)
} finally {
setLoading(false)
}
}, [setLoading, setLogin, setErrors])
return (
<Page>
<Grid centered relaxed divided>
@ -41,7 +54,7 @@ const SettingsPage = connect((state) => ({login: state.login}), {setLogin})(func
<Form onSubmit={handleSubmit(onSave)} loading={loading}>
<Ref innerRef={findInput(register)}>
<Form.Input error={errors?.username} label="Username" name="username" defaultValue={login.username} />
<Form.Input error={errors?.username} label="Username" name="username" defaultValue={login.username} disabled />
</Ref>
<Form.Field error={errors?.bio}>
<label>Bio</label>
@ -62,7 +75,7 @@ const SettingsPage = connect((state) => ({login: state.login}), {setLogin})(func
</Form>
</Grid.Column>
<Grid.Column width={6}>
<ApiKeyDialog {...{login}} />
<ApiKeyDialog {...{login, onGenerateNewKey}} />
<Divider />
@ -101,7 +114,7 @@ function CopyInput({value, ...props}) {
const selectField = findInput((ref) => ref?.select())
function ApiKeyDialog({login}) {
function ApiKeyDialog({login, onGenerateNewKey}) {
const config = useConfig()
const [show, setShow] = React.useState(false)
const onClick = React.useCallback(
@ -112,6 +125,14 @@ function ApiKeyDialog({login}) {
[setShow]
)
const onGenerateNewKeyInner = React.useCallback(
(e) => {
e.preventDefault()
onGenerateNewKey()
},
[onGenerateNewKey]
)
return (
<>
<Header as="h2">Your API Key</Header>
@ -120,11 +141,15 @@ function ApiKeyDialog({login}) {
configuration interface to allow direct upload from the device.
</p>
<p>Please protect your API Key carefully as it allows full control over your account.</p>
<div style={{height: 40, marginBottom: 16}}>
<div style={{minHeight: 40, marginBottom: 16}}>
{show ? (
login.apiKey ? (
<Ref innerRef={selectField}>
<CopyInput label="Personal API key" value={login.apiKey} />
<CopyInput label="Personal API Key" value={login.apiKey} />
</Ref>
) : (
<Message warning content='You have no API Key, please generate one below.' />
)
) : (
<Button onClick={onClick}>
<Icon name="lock" /> Show API Key
@ -132,7 +157,14 @@ function ApiKeyDialog({login}) {
)}
</div>
<p>The API URL should be set to:</p>
<div style={{marginBottom: 16}}>
<CopyInput label="API URL" value={config?.apiUrl ?? '...'} />
</div>
<p>
You can generate a new API Key here, which will invalidate the old one, disconnecting all devices you used it on
from your account.
</p>
<Button onClick={onGenerateNewKeyInner}>Generate new API key</Button>
</>
)
}