client: fix auth errors and wrap markdown headings in links
This commit is contained in:
parent
d75819a02a
commit
59d33042f2
6 changed files with 96 additions and 12 deletions
|
@ -1,5 +1,5 @@
|
|||
import { FormEvent, useState } from 'react'
|
||||
import { Button, Input, Text, useToasts, Note } from '@geist-ui/core'
|
||||
import { Button, Input, Text, Note } from '@geist-ui/core'
|
||||
import styles from './auth.module.css'
|
||||
import { useRouter } from 'next/router'
|
||||
import Link from '../Link'
|
||||
|
@ -15,8 +15,6 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => {
|
|||
const [password, setPassword] = useState('');
|
||||
const [errorMsg, setErrorMsg] = useState('');
|
||||
|
||||
const { setToast } = useToasts();
|
||||
|
||||
const signingIn = page === 'signin'
|
||||
|
||||
const handleJson = (json: any) => {
|
||||
|
@ -29,8 +27,7 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => {
|
|||
|
||||
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (!NO_EMPTY_SPACE_REGEX.test(username) || password.length < 6) return setErrorMsg(ERROR_MESSAGE)
|
||||
if (page === "signup" && (!NO_EMPTY_SPACE_REGEX.test(username) || password.length < 6)) return setErrorMsg(ERROR_MESSAGE)
|
||||
else setErrorMsg('');
|
||||
|
||||
const reqOpts = {
|
||||
|
@ -45,12 +42,13 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => {
|
|||
const signUrl = signingIn ? '/server-api/auth/signin' : '/server-api/auth/signup';
|
||||
const resp = await fetch(signUrl, reqOpts);
|
||||
const json = await resp.json();
|
||||
|
||||
if (!resp.ok) throw new Error();
|
||||
console.log(json)
|
||||
if (!resp.ok) throw new Error(json.error.message);
|
||||
|
||||
handleJson(json)
|
||||
} catch (err: any) {
|
||||
setToast({ text: "Something went wrong", type: 'error' })
|
||||
console.log(err)
|
||||
setErrorMsg(err.message ?? "Something went wrong")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,30 @@
|
|||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* Auto-linked headers */
|
||||
.markdownPreview h1 a,
|
||||
.markdownPreview h2 a,
|
||||
.markdownPreview h3 a,
|
||||
.markdownPreview h4 a,
|
||||
.markdownPreview h5 a,
|
||||
.markdownPreview h6 a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Auto-linked headers */
|
||||
.markdownPreview h1 a:hover::after,
|
||||
.markdownPreview h2 a:hover::after,
|
||||
.markdownPreview h3 a:hover::after,
|
||||
.markdownPreview h4 a:hover::after,
|
||||
.markdownPreview h5 a:hover::after,
|
||||
.markdownPreview h6 a:hover::after {
|
||||
content: " " attr(href);
|
||||
filter: opacity(0.5);
|
||||
font-size: 0.8em;
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdownPreview h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import ReactMarkdown from "react-markdown"
|
||||
import remarkGfm from "remark-gfm"
|
||||
import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import rehypeSlug from 'rehype-slug'
|
||||
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
||||
|
||||
// @ts-ignore because of no types in remark-a11y-emoji
|
||||
import a11yEmoji from '@fec/remark-a11y-emoji';
|
||||
|
||||
import styles from './preview.module.css'
|
||||
import { vscDarkPlus as dark, vs as light } from 'react-syntax-highlighter/dist/cjs/styles/prism'
|
||||
import useSharedState from "@lib/hooks/use-shared-state";
|
||||
|
@ -16,7 +19,9 @@ type Props = {
|
|||
const ReactMarkdownPreview = ({ content, height }: Props) => {
|
||||
const [themeType] = useSharedState<string>('theme')
|
||||
return (<div style={{ height }}>
|
||||
<ReactMarkdown className={styles.markdownPreview} remarkPlugins={[remarkGfm, a11yEmoji]}
|
||||
<ReactMarkdown className={styles.markdownPreview}
|
||||
remarkPlugins={[remarkGfm, a11yEmoji]}
|
||||
rehypePlugins={[rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'wrap' }]]}
|
||||
components={{
|
||||
code({ node, inline, className, children, ...props }) {
|
||||
const match = /language-(\w+)/.exec(className || '')
|
||||
|
@ -50,4 +55,5 @@ const ReactMarkdownPreview = ({ content, height }: Props) => {
|
|||
</ReactMarkdown></div>)
|
||||
}
|
||||
|
||||
|
||||
export default ReactMarkdownPreview
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
"react-markdown": "^8.0.0",
|
||||
"react-syntax-highlighter": "^15.4.5",
|
||||
"react-syntax-highlighter-virtualized-renderer": "^1.1.0",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"rehype-katex": "^6.0.2",
|
||||
"rehype-slug": "^5.0.1",
|
||||
"rehype-stringify": "^9.0.3",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-math": "^5.1.1",
|
||||
|
|
|
@ -1026,6 +1026,11 @@ get-symbol-description@^1.0.0:
|
|||
call-bind "^1.0.2"
|
||||
get-intrinsic "^1.1.1"
|
||||
|
||||
github-slugger@^1.1.1:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.4.0.tgz#206eb96cdb22ee56fdc53a28d5a302338463444e"
|
||||
integrity sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==
|
||||
|
||||
glob-parent@^5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
|
@ -1126,6 +1131,18 @@ hast-util-from-parse5@^7.0.0:
|
|||
vfile-location "^4.0.0"
|
||||
web-namespaces "^2.0.0"
|
||||
|
||||
hast-util-has-property@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-has-property/-/hast-util-has-property-2.0.0.tgz#c15cd6180f3e535540739fcc9787bcffb5708cae"
|
||||
integrity sha512-4Qf++8o5v14us4Muv3HRj+Er6wTNGA/N9uCaZMty4JWvyFKLdhULrv4KE1b65AthsSO9TXSZnjuxS8ecIyhb0w==
|
||||
|
||||
hast-util-heading-rank@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-heading-rank/-/hast-util-heading-rank-2.1.0.tgz#c39f34fa8330ebfec03a08b5d5019ed56122029c"
|
||||
integrity sha512-w+Rw20Q/iWp2Bcnr6uTrYU6/ftZLbHKhvc8nM26VIWpDqDMlku2iXUVTeOlsdoih/UKQhY7PHQ+vZ0Aqq8bxtQ==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
|
||||
hast-util-is-element@^2.0.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-2.1.2.tgz#fc0b0dc7cef3895e839b8d66979d57b0338c68f3"
|
||||
|
@ -1162,6 +1179,13 @@ hast-util-to-html@^8.0.0:
|
|||
stringify-entities "^4.0.2"
|
||||
unist-util-is "^5.0.0"
|
||||
|
||||
hast-util-to-string@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz#b008b0a4ea472bf34dd390b7eea1018726ae152a"
|
||||
integrity sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
|
||||
hast-util-to-text@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-3.1.1.tgz#b7699a75f7a61af6e0befb67660cd78460d96dc6"
|
||||
|
@ -2409,6 +2433,19 @@ regexpp@^3.2.0:
|
|||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
||||
|
||||
rehype-autolink-headings@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/rehype-autolink-headings/-/rehype-autolink-headings-6.1.1.tgz#0cb874a56f3de6ead1c2268d7f0fc5006f244db5"
|
||||
integrity sha512-NMYzZIsHM3sA14nC5rAFuUPIOfg+DFmf9EY1YMhaNlB7+3kK/ZlE6kqPfuxr1tsJ1XWkTrMtMoyHosU70d35mA==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
extend "^3.0.0"
|
||||
hast-util-has-property "^2.0.0"
|
||||
hast-util-heading-rank "^2.0.0"
|
||||
hast-util-is-element "^2.0.0"
|
||||
unified "^10.0.0"
|
||||
unist-util-visit "^4.0.0"
|
||||
|
||||
rehype-katex@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rehype-katex/-/rehype-katex-6.0.2.tgz#20197bbc10bdf79f6b999bffa6689d7f17226c35"
|
||||
|
@ -2433,6 +2470,19 @@ rehype-parse@^8.0.0:
|
|||
parse5 "^6.0.0"
|
||||
unified "^10.0.0"
|
||||
|
||||
rehype-slug@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/rehype-slug/-/rehype-slug-5.0.1.tgz#6e732d0c55b3b1e34187e74b7363fb53229e5f52"
|
||||
integrity sha512-X5v3wV/meuOX9NFcGhJvUpEjIvQl2gDvjg3z40RVprYFt7q3th4qMmYLULiu3gXvbNX1ppx+oaa6JyY1W67pTA==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
github-slugger "^1.1.1"
|
||||
hast-util-has-property "^2.0.0"
|
||||
hast-util-heading-rank "^2.0.0"
|
||||
hast-util-to-string "^2.0.0"
|
||||
unified "^10.0.0"
|
||||
unist-util-visit "^4.0.0"
|
||||
|
||||
rehype-stringify@^9.0.3:
|
||||
version "9.0.3"
|
||||
resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-9.0.3.tgz#70e3bd6d4d29e7acf36b802deed350305d2c3c17"
|
||||
|
|
|
@ -43,13 +43,17 @@ auth.post('/signup', async (req, res, next) => {
|
|||
});
|
||||
|
||||
auth.post('/signin', async (req, res, next) => {
|
||||
const error = "User does not exist or password is incorrect"
|
||||
const errorToThrow = new Error(error);
|
||||
try {
|
||||
validateAuthPayload(req.body.username, req.body.password)
|
||||
if (!req.body.username || !req.body.password) {
|
||||
throw errorToThrow
|
||||
}
|
||||
|
||||
const username = req.body.username.toLowerCase();
|
||||
const user = await User.findOne({ where: { username: username } });
|
||||
if (!user) {
|
||||
throw new Error("User does not exist");
|
||||
throw errorToThrow
|
||||
}
|
||||
|
||||
const password_valid = await compare(req.body.password, user.password);
|
||||
|
@ -57,7 +61,7 @@ auth.post('/signin', async (req, res, next) => {
|
|||
const token = generateAccessToken(user.id);
|
||||
res.status(200).json({ token: token, userId: user.id });
|
||||
} else {
|
||||
throw new Error("Password Incorrect");
|
||||
throw errorToThrow
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
|
Loading…
Reference in a new issue