fix middleware, migrate gist importing

This commit is contained in:
Max Leiter 2022-11-14 18:39:42 -08:00
parent bc2a4acd29
commit 8e7828d562
19 changed files with 98 additions and 86 deletions

View file

@ -17,7 +17,7 @@ const Description = ({ onChange, description }: props) => {
label="Description"
maxLength={256}
width="100%"
placeholder="A short description of your post"
placeholder="An optional description of your post"
/>
</div>
)

View file

@ -1,6 +1,7 @@
import NewPost from "../../components/new"
import { notFound } from "next/navigation"
import { notFound, redirect } from "next/navigation"
import { getPostById } from "@lib/server/prisma"
import { getSession } from "@lib/server/session"
const NewFromExisting = async ({
params
@ -9,6 +10,11 @@ const NewFromExisting = async ({
id: string
}
}) => {
const session = await getSession()
if (!session?.user) {
return redirect("/signin")
}
const { id } = params
if (!id) {

View file

@ -37,10 +37,9 @@ const getPost = async (id: string) => {
return { post, isAuthor: isAuthorOrAdmin }
}
// must be authed to see unlisted/private
if (
(post.visibility === "unlisted" || post.visibility === "private") &&
!user
(post.visibility === "private") &&
!isAuthorOrAdmin
) {
return notFound()
}

View file

@ -0,0 +1,11 @@
import { getAllPosts, getAllUsers } from "@lib/server/prisma"
import styles from "./admin.module.css"
import PostTable from "./post-table"
import UserTable from "./user-table"
const Admin = async () => {
)
}
export default Admin

View file

@ -2,15 +2,15 @@
import SettingsGroup from "@components/settings-group"
import { Fieldset, useToasts } from "@geist-ui/core/dist"
import byteToMB from "@lib/byte-to-mb"
import { Post } from "@lib/server/prisma";
import { PostWithFiles } from "@lib/server/prisma";
import Table from "rc-table"
import { useEffect, useMemo, useState } from "react"
import { useMemo } from "react"
import ActionDropdown from "./action-dropdown"
const PostTable = ({
posts,
}: {
posts: Post[]
posts: PostWithFiles[]
}) => {
const tablePosts = useMemo(
() =>

View file

@ -1,10 +1,7 @@
import type { PostVisibility } from "@lib/types"
import Badge from "../badge"
type CastPostVisibility = PostVisibility | string
type Props = {
visibility: CastPostVisibility
visibility: string
}
const VisibilityBadge = ({ visibility }: Props) => {

View file

@ -1,5 +1,4 @@
import { Button, ButtonGroup, Loading, useToasts } from "@geist-ui/core/dist"
import type { PostVisibility } from "@lib/types"
import PasswordModal from "@components/password-modal"
import { useCallback, useState } from "react"
@ -39,7 +38,7 @@ const VisibilityControl = ({ postId, visibility, setVisibility }: Props) => {
)
const onSubmit = useCallback(
async (visibility: PostVisibility, password?: string) => {
async (visibility: string, password?: string) => {
if (visibility === "protected" && !password) {
setPasswordModalVisible(true)
return

View file

@ -10,7 +10,6 @@ import Parent from "@geist-ui/icons/arrowUpCircle"
import styles from "./list-item.module.css"
import Link from "@components/link"
import type { PostWithFiles } from "@lib/server/prisma"
import type { PostVisibility } from "@lib/types"
import type { File } from "@lib/server/prisma"
import Tooltip from "@components/tooltip"
import Badge from "@components/badges/badge"
@ -76,7 +75,7 @@ const ListItem = ({
)}
<div className={styles.badges}>
<VisibilityBadge visibility={post.visibility as PostVisibility} />
<VisibilityBadge visibility={post.visibility} />
<Badge type="secondary">
{post.files?.length === 1
? "1 file"

View file

@ -1,7 +1,7 @@
"use client"
import { Note, Input, Textarea, Button, useToasts } from "@geist-ui/core/dist"
import { User } from "@lib/server/prisma"
import { User } from "next-auth"
import { useState } from "react"
const Profile = ({ user }: { user: User }) => {

View file

@ -1,5 +1,3 @@
import fetch from "node-fetch"
import { Response } from "node-fetch"
import { Gist, GistFile } from "./types"
async function fetchHelper(response: Response): Promise<Response> {

View file

@ -0,0 +1,68 @@
import { Gist } from "./types"
import * as crypto from "crypto"
import type { Post } from "@lib/server/prisma"
import { getHtmlFromFile } from "@lib/server/get-html-from-drift-file"
import { prisma } from "@lib/server/prisma"
export type AdditionalPostInformation = Pick<
Post,
"visibility" | "password" | "expiresAt"
> & {
userId: string
}
export async function createPostFromGist(
{ userId, visibility, password, expiresAt }: AdditionalPostInformation,
gist: Gist
): Promise<Post> {
const files = Object.values(gist.files)
const [title, description] = gist.description.split("\n", 1)
if (files.length === 0) {
throw new Error("The gist did not have any files")
}
const newPost = await prisma.post.create({
data: {
title,
description,
visibility,
password,
expiresAt,
createdAt: new Date(gist.created_at),
author: {
connect: {
id: userId
}
},
files: {
createMany: {
data: await Promise.all(
files.map(async (file) => {
const content = await file.content()
const html = await getHtmlFromFile({
content,
title: file.filename
})
return {
title: file.filename,
content: content,
sha: crypto
.createHash("sha256")
.update(content)
.digest("hex")
.toString(),
// TODO: shouldn't need this cast
html: html as string,
userId: userId
}
})
)
}
}
}
})
return newPost
}

View file

@ -51,7 +51,7 @@ export const authOptions: NextAuthOptions = {
return {
id: dbUser.id,
name: dbUser.username,
name: dbUser.displayName,
email: dbUser.email,
picture: dbUser.image,
role: dbUser.role || "user",

View file

@ -36,7 +36,7 @@ export default withAuth(
)
export const config = {
match: [
matcher: [
// "/signout",
// "/",
"/signin",

0
client/pages/api/gist.ts Normal file
View file

View file

@ -1,65 +0,0 @@
import getHtmlFromFile from "@lib/get-html-from-drift-file"
import { Post } from "@lib/models/Post"
import { File } from "@lib/models/File"
import { Gist } from "./types"
import * as crypto from "crypto"
export type AdditionalPostInformation = Pick<
Post,
"visibility" | "password" | "expiresAt"
> & {
userId: string
}
export async function createPostFromGist(
{ userId, visibility, password, expiresAt }: AdditionalPostInformation,
gist: Gist
): Promise<Post> {
const files = Object.values(gist.files)
const [title, description] = gist.description.split("\n", 1)
if (files.length === 0) {
throw new Error("The gist did not have any files")
}
const newPost = new Post({
title,
description,
visibility,
password,
expiresAt,
createdAt: new Date(gist.created_at)
})
await newPost.save()
await newPost.$add("users", userId)
const newFiles = await Promise.all(
files.map(async (file) => {
const content = await file.content()
const html = getHtmlFromFile({ content, title: file.filename })
const newFile = new File({
title: file.filename,
content,
sha: crypto
.createHash("sha256")
.update(content)
.digest("hex")
.toString(),
html: html || "",
userId: userId,
postId: newPost.id
})
await newFile.save()
return newFile
})
)
await Promise.all(
newFiles.map(async (file) => {
await newPost.$add("files", file.id)
await newPost.save()
})
)
return newPost
}