aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2024-02-09 19:10:01 +0300
committerGravatar Vitaly Takmazov2024-02-09 19:13:28 +0300
commit9e01a8d3c3daf3257f29ad63b3836dfa89c6200b (patch)
treefc785536ffd05a2232da5222f55e9a5268f99f32
parente2674c3b27174e408264b84f50bf86a13e2d3824 (diff)
vnext: authorize on backend
-rw-r--r--vnext/src/App.js27
-rw-r--r--vnext/src/api/index.js34
-rw-r--r--vnext/src/index.js9
-rw-r--r--vnext/src/ui/Feeds.js2
-rw-r--r--vnext/src/ui/Login.js88
-rw-r--r--vnext/src/ui/Message.js4
6 files changed, 20 insertions, 144 deletions
diff --git a/vnext/src/App.js b/vnext/src/App.js
index c7849418..f20d8db3 100644
--- a/vnext/src/App.js
+++ b/vnext/src/App.js
@@ -1,5 +1,5 @@
import { useState, useEffect, useRef, Fragment, useCallback } from 'react'
-import { Route, Link, Routes, useSearchParams } from 'react-router-dom'
+import { Route, Link, Routes } from 'react-router-dom'
import svg4everybody from 'svg4everybody'
@@ -12,11 +12,8 @@ import Chat from './ui/Chat'
import Header from './ui/Header'
import Post from './ui/Post'
import Thread from './ui/Thread'
-import Login from './ui/Login'
-import { useCookies } from 'react-cookie'
-
-import { me, trends } from './api'
+import { loginUrl, me, trends } from './api'
import { useVisitor } from './ui/VisitorContext'
import Avatar from './ui/Avatar'
import { Toaster } from 'react-hot-toast'
@@ -30,22 +27,20 @@ import { Toaster } from 'react-hot-toast'
export default function App({ footer }) {
let contentRef = useRef(null)
- const [, setCookie] = useCookies(['hash'])
const [allTrends, setAllTrends] = useState([])
const [visitor, setVisitor] = useVisitor()
- const params = useSearchParams()
-
useEffect(() => {
svg4everybody()
+ /*
if (params['hash']) {
setCookie('hash', params['hash'], { path: '/' })
let retpath = params['retpath'] || `${window.location.protocol}//${window.location.host}${window.location.pathname}`
window.history.replaceState({}, document.title, retpath)
- }
- }, [setCookie, footer, params])
+ }*/
+ }, [])
let updateStatus = useCallback(() => {
// refresh server visitor state (unread counters)
@@ -60,10 +55,9 @@ export default function App({ footer }) {
let es
if (visitor) {
if ('EventSource' in window) {
- const eventParams = new URLSearchParams({ hash: visitor.hash })
- let url = new URL(`https://juick.com/api/events?${eventParams.toString()}`)
- console.log(url.toString())
- es = new EventSource(url.toString())
+ es = new EventSource('/api/events', {
+ withCredentials: true
+ })
es.onopen = () => {
console.log('online')
}
@@ -123,10 +117,10 @@ export default function App({ footer }) {
<span className="desktop">Settings</span>
</Link>
</> :
- <Link to={{ pathname: '/login' }}>
+ <a href={`/login?retpath=${window.location.href}`}>
<Icon name="ei-user" size="s" />
<span className="desktop">Login</span>
- </Link>
+ </a>
}
<Link to={{ pathname: '/discover' }} rel="nofollow">
<Icon name="ei-search" size="s" />
@@ -168,7 +162,6 @@ export default function App({ footer }) {
<Route exact path="/home" element={<Home />} />
<Route exact path="/discover" element={<Discover />} />
<Route exact path="/settings" element={<Settings onChange={updateStatus} />} />
- <Route exact path="/login" element={<Login onAuth={updateStatus} />} />
<Route exact path="/post" element={<Post />} />
<Route exact path="/pm" element={<Contacts />} />
<Route exact path="/pm/:user" element={<Chat connection={eventSource} />} />
diff --git a/vnext/src/api/index.js b/vnext/src/api/index.js
index 24f2fe88..4d2a81fa 100644
--- a/vnext/src/api/index.js
+++ b/vnext/src/api/index.js
@@ -1,5 +1,4 @@
import axios from 'axios'
-import Cookies from 'universal-cookie'
const apiBaseUrl = 'https://juick.com'
@@ -72,41 +71,16 @@ const apiBaseUrl = 'https://juick.com'
const client = axios.create({
- baseURL: apiBaseUrl
-})
-client.interceptors.request.use(config => {
- if (config.url.startsWith('/')) {
- // only local URLs
- let cookies = new Cookies()
- config.params = Object.assign(config.params || {}, {
- hash: cookies.get('hash')
- })
- }
- return config
+ baseURL: apiBaseUrl,
+ withCredentials: true
})
/**
* fetch my info
- * @param {string=} username
- * @param {string=} password
* @returns {Promise<SecureUser, Error>} me object
*/
-export function me(username, password) {
- let cookies = new Cookies()
- return new Promise((resolve, reject) => {
- client.get('/api/me', {
- headers: username ? {
- 'Authorization': 'Basic ' + window.btoa(unescape(encodeURIComponent(username + ':' + password)))
- } : {}
- }).then(response => {
- let visitor = response.data
- cookies.set('hash', visitor.hash, { path: '/' })
- resolve(visitor)
- }).catch(reason => {
- cookies.remove('hash', { path: '/' })
- reject(reason)
- })
- })
+export function me() {
+ return client.get('/api/me')
}
/**
diff --git a/vnext/src/index.js b/vnext/src/index.js
index f648b105..aa39e810 100644
--- a/vnext/src/index.js
+++ b/vnext/src/index.js
@@ -11,7 +11,6 @@ import 'url-polyfill'
import { StrictMode, lazy } from 'react'
import { createRoot, hydrateRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
-import { CookiesProvider } from 'react-cookie'
import { HelmetProvider } from 'react-helmet-async'
import { VisitorProvider } from './ui/VisitorContext'
@@ -39,11 +38,9 @@ ready(async () => {
<StrictMode>
<HelmetProvider>
<VisitorProvider auth={visitor}>
- <CookiesProvider>
- <BrowserRouter>
- <Juick {...props} />
- </BrowserRouter>
- </CookiesProvider>
+ <BrowserRouter>
+ <Juick {...props} />
+ </BrowserRouter>
</VisitorProvider>
</HelmetProvider>
</StrictMode>
diff --git a/vnext/src/ui/Feeds.js b/vnext/src/ui/Feeds.js
index 16b6b534..0cebdce6 100644
--- a/vnext/src/ui/Feeds.js
+++ b/vnext/src/ui/Feeds.js
@@ -35,7 +35,7 @@ function RequireAuth({ children }) {
// trying to go to when they were redirected. This allows us to send them
// along to that page after they login, which is a nicer user experience
// than dropping them off on the home page.
- return <Navigate to="/login" state={{ from: location }} />
+ return <Navigate to={`/login?retpath=${window.location.href}`} state={{ from: location }} />
}
return children
diff --git a/vnext/src/ui/Login.js b/vnext/src/ui/Login.js
deleted file mode 100644
index ed0e990c..00000000
--- a/vnext/src/ui/Login.js
+++ /dev/null
@@ -1,88 +0,0 @@
-import { useEffect } from 'react'
-import { useLocation, useNavigate } from 'react-router-dom'
-
-import Icon from './Icon'
-import Button from './Button'
-import { useForm } from 'react-hook-form'
-
-import { me, facebookLink, vkLink, appleLink } from '../api'
-
-import { useVisitor } from './VisitorContext'
-
-/**
- * @typedef {object} LoginProps
- * @property {Function} onAuth
- */
-
-/**
- * Login page
- * @param {LoginProps} props
- */
-function Login({ onAuth }) {
- const location = useLocation()
- const navigate = useNavigate()
- const [visitor] = useVisitor()
- useEffect(() => {
- if (visitor && visitor.hash) {
- const retpath = location.state?.retpath || '/'
- console.log(retpath)
- navigate(retpath)
- }
- }, [navigate, location.state, visitor])
-
- const { register, handleSubmit } = useForm()
-
- /** @type { import('react-hook-form').SubmitHandler<import('react-hook-form').FieldValues> } */
- let onSubmit = (values) => {
- me(values.username, values.password)
- .then(response => {
- onAuth(response)
- }
- ).catch(ex => {
- console.log(ex)
- })
- }
- return (
- <div className="msg-cont">
- <div className="dialoglogin">
- <p>Please, introduce yourself:</p>
- <div style={socialButtonsStyle}>
- <a href={facebookLink()} style={facebookButtonStyle}>
- <Icon name="ei-sc-facebook" size="s" noFill={true} />Log in
- </a>
- <a href={vkLink()} style={vkButtonStyle}>
- <Icon name="ei-sc-vk" size="s" noFill={true} />
- Log in
- </a>
- <a href={appleLink()}><img src="https://appleid.cdn-apple.com/appleid/button" /></a>
- </div>
- <p>Already registered?</p>
- <form onSubmit={handleSubmit(onSubmit)}>
- <input placeholder="Username..." {...register('username')} /><br />
- <input placeholder="Password..." type="password" {...register('password')} /><br />
- <Button onClick={handleSubmit(onSubmit)}>OK</Button>
- </form>
- </div>
- </div>
- )
-}
-
-export default Login
-
-const socialButtonsStyle = {
- display: 'flex',
- justifyContent: 'space-evenly',
- padding: '4px'
-}
-
-const facebookButtonStyle = {
- color: '#fff',
- padding: '2px 14px',
- background: '#3b5998'
-}
-
-const vkButtonStyle = {
- color: '#fff',
- padding: '2px 14px',
- background: '#4c75a3'
-}
diff --git a/vnext/src/ui/Message.js b/vnext/src/ui/Message.js
index eba0f327..eaac8eba 100644
--- a/vnext/src/ui/Message.js
+++ b/vnext/src/ui/Message.js
@@ -112,10 +112,10 @@ export default function Message({ data, isThread, onToggleSubscription, children
<span>{likesSummary}</span>
</Link>
) : (
- <Link to="/login" className="a-login msg-button">
+ <a href={`/login?retpath=${window.location.href}`} className="a-login msg-button">
<Icon name="ei-heart" size="s" />
<span>{likesSummary}</span>
- </Link>
+ </a>
)}
{
data.user && canComment && ((