diff options
author | Vitaly Takmazov | 2024-02-09 19:10:01 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2024-02-09 19:13:28 +0300 |
commit | 9e01a8d3c3daf3257f29ad63b3836dfa89c6200b (patch) | |
tree | fc785536ffd05a2232da5222f55e9a5268f99f32 /vnext/src | |
parent | e2674c3b27174e408264b84f50bf86a13e2d3824 (diff) |
vnext: authorize on backend
Diffstat (limited to 'vnext/src')
-rw-r--r-- | vnext/src/App.js | 27 | ||||
-rw-r--r-- | vnext/src/api/index.js | 34 | ||||
-rw-r--r-- | vnext/src/index.js | 9 | ||||
-rw-r--r-- | vnext/src/ui/Feeds.js | 2 | ||||
-rw-r--r-- | vnext/src/ui/Login.js | 88 | ||||
-rw-r--r-- | vnext/src/ui/Message.js | 4 |
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 && (( |