Skip to content

Commit

Permalink
feat: add password view history, closes #6
Browse files Browse the repository at this point in the history
  • Loading branch information
Arcath committed Mar 5, 2024
1 parent e1bde68 commit f615741
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 33 deletions.
5 changes: 5 additions & 0 deletions app/lib/utils/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {format} from 'date-fns'

export const formatAsDateTime = (ts: string) => {
return format(new Date(ts), 'KK:mm EEEE do yyyy')
}
6 changes: 5 additions & 1 deletion app/routes/api.password.$password.get.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {getPrisma} from '~/lib/prisma.server'
import {getCryptoSuite} from '~/lib/crypto.server'

export const loader = async ({request, params}: LoaderFunctionArgs) => {
await ensureUser(request, 'password:get', {
const user = await ensureUser(request, 'password:get', {
passwordId: params.password
})

Expand All @@ -15,6 +15,10 @@ export const loader = async ({request, params}: LoaderFunctionArgs) => {
where: {id: params.password}
})

await prisma.passwordView.create({
data: {userId: user.id, passwordId: password.id}
})

const {decrypt} = await getCryptoSuite()

return json({password: decrypt(password.password)})
Expand Down
90 changes: 58 additions & 32 deletions app/routes/app.passwords.$password._index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {type LoaderFunctionArgs, json} from '@remix-run/node'
import {useLoaderData} from '@remix-run/react'
import {useState} from 'react'
import {useQuery} from '@tanstack/react-query'

import {ensureUser} from '~/lib/utils/ensure-user'
import {getPrisma} from '~/lib/prisma.server'
import {AButton} from '~/lib/components/button'
import {buildMDXBundle} from '~/lib/mdx.server'
import {MDXComponent} from '~/lib/mdx'
import {useQuery} from '@tanstack/react-query'
import {formatAsDateTime} from '~/lib/utils/format'

export const loader = async ({request, params}: LoaderFunctionArgs) => {
const user = await ensureUser(request, 'password:view', {
Expand All @@ -17,7 +18,13 @@ export const loader = async ({request, params}: LoaderFunctionArgs) => {
const prisma = getPrisma()

const password = await prisma.password.findFirstOrThrow({
select: {id: true, title: true, username: true, notes: true},
select: {
id: true,
title: true,
username: true,
notes: true,
views: {include: {user: true}, take: 10, orderBy: {createdAt: 'desc'}}
},
where: {id: params.password}
})

Expand All @@ -44,36 +51,55 @@ const AssetManagerAsset = () => {
})

return (
<div>
<h4 className="text-xl">{password.title}</h4>
<AButton href={`/app/passwords/${password.id}/edit`} className="bg-info">
Edit
</AButton>
<p>
<b>Username</b>
<br />
{password.username}
</p>
<p>
<b>Password</b>
<br />
{passwordOpen ? (
<span>{isPending ? '⌛' : data}</span>
) : (
<button
onClick={() => {
setPasswordOpen(true)
refetch()
}}
>
🔒
</button>
)}
</p>
<p>
<b>Notes</b>
</p>
<MDXComponent code={code} />
<div className="grid grid-cols-3">
<div className="col-span-2">
<h4 className="text-xl">{password.title}</h4>
<AButton
href={`/app/passwords/${password.id}/edit`}
className="bg-info"
>
Edit
</AButton>
<p>
<b>Username</b>
<br />
{password.username}
</p>
<p>
<b>Password</b>
<br />
{passwordOpen ? (
<span>{isPending ? '⌛' : data}</span>
) : (
<button
onClick={() => {
setPasswordOpen(true)
refetch()
}}
>
🔒
</button>
)}
</p>
<p>
<b>Notes</b>
</p>
<MDXComponent code={code} />
</div>
<div>
<h3>View History</h3>
{password.views.map(({id, user, createdAt}) => {
return (
<div key={id}>
{user.name}
<br />
<span className="text-gray-400">
{formatAsDateTime(createdAt)}
</span>
</div>
)
})}
</div>
</div>
)
}
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@tanstack/react-query": "^5.24.1",
"bcrypt": "^5.1.1",
"cancant": "^1.1.0",
"date-fns": "^3.3.1",
"isbot": "^4.1.0",
"mdx-bundler": "^10.0.1",
"qrcode": "^1.5.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- CreateTable
CREATE TABLE "PasswordView" (
"id" TEXT NOT NULL PRIMARY KEY,
"userId" TEXT NOT NULL,
"passwordId" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "PasswordView_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "PasswordView_passwordId_fkey" FOREIGN KEY ("passwordId") REFERENCES "Password" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
11 changes: 11 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ model User {
pastValueEdits ValueHistory[]
documentChanges DocumentHistory[]
passwordChanges PasswordHistory[]
passwordViews PasswordView[]
}

model Session {
Expand Down Expand Up @@ -146,6 +147,7 @@ model Password {
history PasswordHistory[]
entries EntryPassword[]
views PasswordView[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Expand All @@ -167,6 +169,15 @@ model PasswordHistory {
updatedAt DateTime @updatedAt
}

model PasswordView {
id String @id @default(uuid())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
password Password @relation(fields: [passwordId], references: [id], onDelete: Cascade)
passwordId String
createdAt DateTime @default(now())
}

model EntryPassword {
id String @id @default(uuid())
entry Entry @relation(fields: [entryId], references: [id], onDelete: Cascade)
Expand Down

0 comments on commit f615741

Please sign in to comment.