Skip to content

Commit

Permalink
add ability to manually input web-player user auth token
Browse files Browse the repository at this point in the history
  • Loading branch information
danreeves committed Dec 27, 2023
1 parent 732d6d2 commit 95647bf
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 15 deletions.
24 changes: 24 additions & 0 deletions app/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from "react"

import { cn } from "app/utils/cn"

export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}

const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
)
}
)
Textarea.displayName = "Textarea"

export { Textarea }
103 changes: 88 additions & 15 deletions app/routes/_pages.settings.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"
import { json } from "@remix-run/node"
import { deleteAuthToken, getAuthToken } from "~/services/db/authtoken.server"
import {
deleteAuthToken,
getAuthToken,
updateAuthToken,
} from "~/services/db/authtoken.server"
import type { User } from "~/services/auth.server"
import { authenticator } from "~/services/auth.server"
import { Form, useLoaderData } from "@remix-run/react"

import { Button } from "~/components/ui/button"
import { Trash2 } from "lucide-react"
import { Label, TextField } from "react-aria-components"
import { Textarea } from "~/components/ui/textarea"
import { number, object, parse, string } from "valibot"
import { refreshToken } from "~/services/darktide.server"

export async function loader({ request }: LoaderFunctionArgs) {
let user = await authenticator.isAuthenticated(request, {
Expand All @@ -24,30 +33,94 @@ export async function loader({ request }: LoaderFunctionArgs) {
return json({ title: "Settings", hasAuthToken })
}

const AuthDataSchema = object({
AccessToken: string(),
RefreshToken: string(),
ExpiresIn: number(),
Sub: string(),
AccountName: string(),
RefreshAt: number(),
})

async function authoriseUser(userdata: string, user: User) {
let json: unknown

try {
json = JSON.parse(userdata)
} catch (e) {
throw new Error("Invalid JSON")
}

let data = parse(AuthDataSchema, json)

let newToken = await refreshToken(data.RefreshToken)

if (newToken) {
let expiresAt = new Date()
expiresAt.setSeconds(expiresAt.getSeconds() + newToken.ExpiresIn)

await updateAuthToken({
userId: user.id,
expiresAt: expiresAt,
sub: newToken.Sub,
accessToken: newToken.AccessToken,
refreshToken: newToken.RefreshToken,
})
}
}

export async function action({ request }: ActionFunctionArgs) {
let user = await authenticator.isAuthenticated(request, {
failureRedirect: "/login",
})
await deleteAuthToken(user.id)

const formData = await request.clone().formData()
const action = formData.get("_action")

if (action === "DELETE_AUTH") {
await deleteAuthToken(user.id)
}

if (action === "ADD_AUTH") {
authoriseUser(String(formData.get("userdata")), user)
}

return true
}

export default function Settings() {
let { hasAuthToken } = useLoaderData<typeof loader>()

return (
<div className="p-4 rounded-lg border bg-card text-card-foreground shadow-smw">
<Form method="post" className="flex flex-row items-center gap-6">
<Button variant="destructive" type="submit" disabled={!hasAuthToken}>
<Trash2 className="block h-6 w-6" aria-hidden="true" />
Delete authentication token
</Button>

<p>
Delete your authentication token? You'll no longer be able to use the
Armoury features of this site.
</p>
</Form>
</div>
<>
<div className="p-4 mb-4 rounded-lg border bg-card text-card-foreground shadow-smw">
<Form method="post" className="flex flex-row items-center gap-6">
<input type="hidden" name="_action" value="DELETE_AUTH" />

<Button variant="destructive" type="submit" disabled={!hasAuthToken}>
<Trash2 className="block h-4 w-4 mr-1" aria-hidden="true" />
Delete authentication token
</Button>

<p>
Delete your authentication token? You'll no longer be able to use
the Armoury features of this site.
</p>
</Form>
</div>

<div className="p-4 rounded-lg border bg-card text-card-foreground shadow-smw">
<Form method="post" className="flex flex-col items-center gap-6">
<input type="hidden" name="_action" value="ADD_AUTH" />

<TextField className="grid w-full gap-1.5">
<Label>Paste user json here:</Label>
<Textarea name="userdata" />
</TextField>

<Button type="submit">Authorise</Button>
</Form>
</div>
</>
)
}

0 comments on commit 95647bf

Please sign in to comment.