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 { 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 styles from './auth.module.css'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import Link from '../Link'
|
import Link from '../Link'
|
||||||
|
@ -15,8 +15,6 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => {
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const [errorMsg, setErrorMsg] = useState('');
|
const [errorMsg, setErrorMsg] = useState('');
|
||||||
|
|
||||||
const { setToast } = useToasts();
|
|
||||||
|
|
||||||
const signingIn = page === 'signin'
|
const signingIn = page === 'signin'
|
||||||
|
|
||||||
const handleJson = (json: any) => {
|
const handleJson = (json: any) => {
|
||||||
|
@ -29,8 +27,7 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => {
|
||||||
|
|
||||||
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
if (page === "signup" && (!NO_EMPTY_SPACE_REGEX.test(username) || password.length < 6)) return setErrorMsg(ERROR_MESSAGE)
|
||||||
if (!NO_EMPTY_SPACE_REGEX.test(username) || password.length < 6) return setErrorMsg(ERROR_MESSAGE)
|
|
||||||
else setErrorMsg('');
|
else setErrorMsg('');
|
||||||
|
|
||||||
const reqOpts = {
|
const reqOpts = {
|
||||||
|
@ -45,12 +42,13 @@ const Auth = ({ page }: { page: "signup" | "signin" }) => {
|
||||||
const signUrl = signingIn ? '/server-api/auth/signin' : '/server-api/auth/signup';
|
const signUrl = signingIn ? '/server-api/auth/signin' : '/server-api/auth/signup';
|
||||||
const resp = await fetch(signUrl, reqOpts);
|
const resp = await fetch(signUrl, reqOpts);
|
||||||
const json = await resp.json();
|
const json = await resp.json();
|
||||||
|
console.log(json)
|
||||||
if (!resp.ok) throw new Error();
|
if (!resp.ok) throw new Error(json.error.message);
|
||||||
|
|
||||||
handleJson(json)
|
handleJson(json)
|
||||||
} catch (err: any) {
|
} 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;
|
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 {
|
.markdownPreview h1 {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import ReactMarkdown from "react-markdown"
|
import ReactMarkdown from "react-markdown"
|
||||||
import remarkGfm from "remark-gfm"
|
import remarkGfm from "remark-gfm"
|
||||||
import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter';
|
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
|
// @ts-ignore because of no types in remark-a11y-emoji
|
||||||
import a11yEmoji from '@fec/remark-a11y-emoji';
|
import a11yEmoji from '@fec/remark-a11y-emoji';
|
||||||
|
|
||||||
import styles from './preview.module.css'
|
import styles from './preview.module.css'
|
||||||
import { vscDarkPlus as dark, vs as light } from 'react-syntax-highlighter/dist/cjs/styles/prism'
|
import { vscDarkPlus as dark, vs as light } from 'react-syntax-highlighter/dist/cjs/styles/prism'
|
||||||
import useSharedState from "@lib/hooks/use-shared-state";
|
import useSharedState from "@lib/hooks/use-shared-state";
|
||||||
|
@ -16,7 +19,9 @@ type Props = {
|
||||||
const ReactMarkdownPreview = ({ content, height }: Props) => {
|
const ReactMarkdownPreview = ({ content, height }: Props) => {
|
||||||
const [themeType] = useSharedState<string>('theme')
|
const [themeType] = useSharedState<string>('theme')
|
||||||
return (<div style={{ height }}>
|
return (<div style={{ height }}>
|
||||||
<ReactMarkdown className={styles.markdownPreview} remarkPlugins={[remarkGfm, a11yEmoji]}
|
<ReactMarkdown className={styles.markdownPreview}
|
||||||
|
remarkPlugins={[remarkGfm, a11yEmoji]}
|
||||||
|
rehypePlugins={[rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'wrap' }]]}
|
||||||
components={{
|
components={{
|
||||||
code({ node, inline, className, children, ...props }) {
|
code({ node, inline, className, children, ...props }) {
|
||||||
const match = /language-(\w+)/.exec(className || '')
|
const match = /language-(\w+)/.exec(className || '')
|
||||||
|
@ -50,4 +55,5 @@ const ReactMarkdownPreview = ({ content, height }: Props) => {
|
||||||
</ReactMarkdown></div>)
|
</ReactMarkdown></div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default ReactMarkdownPreview
|
export default ReactMarkdownPreview
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
"react-markdown": "^8.0.0",
|
"react-markdown": "^8.0.0",
|
||||||
"react-syntax-highlighter": "^15.4.5",
|
"react-syntax-highlighter": "^15.4.5",
|
||||||
"react-syntax-highlighter-virtualized-renderer": "^1.1.0",
|
"react-syntax-highlighter-virtualized-renderer": "^1.1.0",
|
||||||
|
"rehype-autolink-headings": "^6.1.1",
|
||||||
"rehype-katex": "^6.0.2",
|
"rehype-katex": "^6.0.2",
|
||||||
|
"rehype-slug": "^5.0.1",
|
||||||
"rehype-stringify": "^9.0.3",
|
"rehype-stringify": "^9.0.3",
|
||||||
"remark-gfm": "^3.0.1",
|
"remark-gfm": "^3.0.1",
|
||||||
"remark-math": "^5.1.1",
|
"remark-math": "^5.1.1",
|
||||||
|
|
|
@ -1026,6 +1026,11 @@ get-symbol-description@^1.0.0:
|
||||||
call-bind "^1.0.2"
|
call-bind "^1.0.2"
|
||||||
get-intrinsic "^1.1.1"
|
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:
|
glob-parent@^5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
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"
|
vfile-location "^4.0.0"
|
||||||
web-namespaces "^2.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:
|
hast-util-is-element@^2.0.0:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-2.1.2.tgz#fc0b0dc7cef3895e839b8d66979d57b0338c68f3"
|
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"
|
stringify-entities "^4.0.2"
|
||||||
unist-util-is "^5.0.0"
|
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:
|
hast-util-to-text@^3.1.0:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-3.1.1.tgz#b7699a75f7a61af6e0befb67660cd78460d96dc6"
|
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"
|
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
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:
|
rehype-katex@^6.0.2:
|
||||||
version "6.0.2"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/rehype-katex/-/rehype-katex-6.0.2.tgz#20197bbc10bdf79f6b999bffa6689d7f17226c35"
|
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"
|
parse5 "^6.0.0"
|
||||||
unified "^10.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:
|
rehype-stringify@^9.0.3:
|
||||||
version "9.0.3"
|
version "9.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-9.0.3.tgz#70e3bd6d4d29e7acf36b802deed350305d2c3c17"
|
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) => {
|
auth.post('/signin', async (req, res, next) => {
|
||||||
|
const error = "User does not exist or password is incorrect"
|
||||||
|
const errorToThrow = new Error(error);
|
||||||
try {
|
try {
|
||||||
validateAuthPayload(req.body.username, req.body.password)
|
if (!req.body.username || !req.body.password) {
|
||||||
|
throw errorToThrow
|
||||||
|
}
|
||||||
|
|
||||||
const username = req.body.username.toLowerCase();
|
const username = req.body.username.toLowerCase();
|
||||||
const user = await User.findOne({ where: { username: username } });
|
const user = await User.findOne({ where: { username: username } });
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new Error("User does not exist");
|
throw errorToThrow
|
||||||
}
|
}
|
||||||
|
|
||||||
const password_valid = await compare(req.body.password, user.password);
|
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);
|
const token = generateAccessToken(user.id);
|
||||||
res.status(200).json({ token: token, userId: user.id });
|
res.status(200).json({ token: token, userId: user.id });
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Password Incorrect");
|
throw errorToThrow
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
Loading…
Reference in a new issue