From f7238ab0913fbc02a1440c908d7efae2cc91a0a1 Mon Sep 17 00:00:00 2001 From: Katalina / stardust Date: Wed, 17 Jan 2018 23:12:11 -0600 Subject: [PATCH] fix redirects, fix server syncs on join --- Server/api/servers.js | 19 ++++++++- Server/services/discord.js | 5 +++ Server/services/presentation.js | 16 +++++--- UI/package.json | 1 + UI/src/actions/index.js | 5 ++- UI/src/components/add-server/index.js | 4 +- UI/src/components/oauth-callback/index.js | 16 ++++++-- UI/src/components/oauth-flow/index.js | 11 +++-- UI/src/components/servers/ServerLanding.js | 47 ++++++++++++++++++++++ UI/src/components/servers/index.js | 24 +++++------ UI/src/pages/Error404.js | 33 +++------------ UI/src/pages/ServerLanding.js | 35 ---------------- UI/src/pages/index.js | 1 - UI/src/router/index.js | 16 ++++---- 14 files changed, 132 insertions(+), 101 deletions(-) create mode 100644 UI/src/components/servers/ServerLanding.js delete mode 100644 UI/src/pages/ServerLanding.js diff --git a/Server/api/servers.js b/Server/api/servers.js index 5da9905..20421a6 100644 --- a/Server/api/servers.js +++ b/Server/api/servers.js @@ -7,7 +7,7 @@ module.exports = (R, $) => { ctx.body = presentable } catch (e) { - console.error(e.trace) + console.error(e.trace || e.stack) } }) @@ -29,6 +29,23 @@ module.exports = (R, $) => { ctx.body = server }) + R.get('/api/server/:id/slug', async (ctx) => { + const { userId } = ctx.session + const { id } = ctx.params + + const srv = $.discord.client.guilds.get(id) + + console.log(srv) + + if (srv == null) { + ctx.body = { err: 'not found' } + ctx.status = 404 + return + } + + ctx.body = await $.P.serverSlug(srv) + }) + R.patch('/api/server/:id', async (ctx) => { const { userId } = ctx.session const { id } = ctx.params diff --git a/Server/services/discord.js b/Server/services/discord.js index f12ae59..8352cc4 100644 --- a/Server/services/discord.js +++ b/Server/services/discord.js @@ -34,6 +34,7 @@ class DiscordService extends Service { if (this.isBot) { this.log.info('this roleypoly is a bot') this.client.on('message', this.handleMessage.bind(this)) + this.client.on('guildCreate', this.handleJoin.bind(this)) } for (let server of this.client.guilds.array()) { @@ -216,6 +217,10 @@ class DiscordService extends Service { } } + async handleJoin (guild) { + await this.ctx.server.ensure(guild) + } + } module.exports = DiscordService diff --git a/Server/services/presentation.js b/Server/services/presentation.js index e150511..3212063 100644 --- a/Server/services/presentation.js +++ b/Server/services/presentation.js @@ -10,6 +10,15 @@ class PresentationService extends Service { this.cache = LRU({ max: 500, maxAge: 100 * 60 * 5 }) } + serverSlug (server) { + return { + id: server.id, + name: server.name, + ownerID: server.ownerID, + icon: server.icon + } + } + async oldPresentableServers (collection, userId) { let servers = [] @@ -39,12 +48,7 @@ class PresentationService extends Service { nickname: gm.nickname, color: gm.displayHexColor }, - server: { - id: server.id, - name: server.name, - ownerID: server.ownerID, - icon: server.icon - }, + server: this.serverSlug(server), roles: (incRoles) ? (await this.rolesByServer(server, sd)).map(r => ({ ...r, selected: gm.roles.has(r.id) })) : [], message: sd.message, categories: sd.categories, diff --git a/UI/package.json b/UI/package.json index fb76e73..42e3ad7 100644 --- a/UI/package.json +++ b/UI/package.json @@ -33,6 +33,7 @@ "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, + "homepage": "https://rp.kat.cafe", "proxy": { "/api": { "target": "http://localhost:6769" diff --git a/UI/src/actions/index.js b/UI/src/actions/index.js index b277194..47dbe67 100644 --- a/UI/src/actions/index.js +++ b/UI/src/actions/index.js @@ -39,7 +39,10 @@ export const userInit = async dispatch => { } export const userLogout = async dispatch => { - await superagent.post('/api/auth/logout') + try { + await superagent.post('/api/auth/logout') + } catch (e) { + } dispatch({ type: Symbol.for('reset user') diff --git a/UI/src/components/add-server/index.js b/UI/src/components/add-server/index.js index 97355e3..7e4bd74 100644 --- a/UI/src/components/add-server/index.js +++ b/UI/src/components/add-server/index.js @@ -10,7 +10,9 @@ export default class AddServer extends Component { polling = null componentDidMount () { - this.pollingStop = Actions.startServerPolling(this.props.dispatch) + if (this.props.match.params.server !== undefined) { + this.pollingStop = Actions.startServerPolling(this.props.dispatch) + } } componentWillUnmount () { diff --git a/UI/src/components/oauth-callback/index.js b/UI/src/components/oauth-callback/index.js index c593105..a85a2ac 100644 --- a/UI/src/components/oauth-callback/index.js +++ b/UI/src/components/oauth-callback/index.js @@ -8,18 +8,26 @@ import { fetchServers } from '../../actions' class OauthCallback extends Component { state = { notReady: true, - message: 'chotto matte kudasai...' + message: 'chotto matte kudasai...', + redirect: '/s' } async componentDidMount () { // handle stuff in the url const sp = new URLSearchParams(this.props.location.search) const token = sp.get('code') - + if (token === '' || token == null) { this.setState({ message: 'token missing, what are you trying to do?!' }) return } + + const stateToken = sp.get('state') + const state = JSON.parse(window.sessionStorage.getItem('state') || 'null') + + if (state !== null && state.state === stateToken && state.redirect != undefined) { + this.setState({ redirect: state.redirect }) + } this.props.history.replace(this.props.location.pathname) @@ -35,7 +43,7 @@ class OauthCallback extends Component { this.props.dispatch(fetchServers) } catch (e) { counter++ - if (counter > 12) { + if (counter > 100) { this.setState({ message: "i couldn't log you in. :c" }) } else { setTimeout(() => { retry() }, 250) @@ -61,7 +69,7 @@ class OauthCallback extends Component { } render () { - return (this.state.notReady) ? this.state.message : + return (this.state.notReady) ? this.state.message : } } diff --git a/UI/src/components/oauth-flow/index.js b/UI/src/components/oauth-flow/index.js index 200e853..6b1f53f 100644 --- a/UI/src/components/oauth-flow/index.js +++ b/UI/src/components/oauth-flow/index.js @@ -2,8 +2,9 @@ import React, { Component } from 'react' import { Redirect } from 'react-router-dom' import superagent from 'superagent' import { connect } from 'react-redux' +import uuidv4 from 'uuid/v4' import { fetchServers } from '../../actions' -import { URL } from 'url'; + @connect() class OauthCallback extends Component { @@ -39,11 +40,15 @@ class OauthCallback extends Component { } async componentDidMount () { + const state = uuidv4() + const oUrl = new URL(window.location.href) if (oUrl.searchParams.has('r')) { this.setState({ redirect: oUrl.searchParams.get('r') }) } + window.sessionStorage.setItem('state', JSON.stringify({ state, redirect: oUrl.searchParams.get('r') })) + try { await this.setupUser() @@ -53,9 +58,7 @@ class OauthCallback extends Component { const { body: { url } } = await superagent.get('/api/auth/redirect?url=✔️') const nUrl = new URL(url) - if (oUrl.searchParams.has('r')) { - nUrl.searchParams.set('r', oUrl.searchParams.get('r')) - } + nUrl.searchParams.set('state', state) window.location.href = nUrl.toString() } diff --git a/UI/src/components/servers/ServerLanding.js b/UI/src/components/servers/ServerLanding.js new file mode 100644 index 0000000..99253a5 --- /dev/null +++ b/UI/src/components/servers/ServerLanding.js @@ -0,0 +1,47 @@ +import React, { Component } from 'react' +import { Link, Redirect } from 'react-router-dom' +import superagent from 'superagent' +import discordLogo from '../../pages/images/discord-logo.svg' + +export default class ServerLanding extends Component { + state = { + server: null, + exit: false + } + + async componentWillMount () { + console.log(this.props) + + try { + const rsp = await superagent.get(`/api/server/${this.props.match.params.server}/slug`) + this.setState({ server: rsp.body }) + } catch (e) { + this.setState({ exit: true }) + return + } + + } + + render () { + if (this.state.exit === true) { + return + } + + if (this.state.server === null) { + return null //SPINNER + } + + return
+
+
+

Hey there.

+

{this.state.server.name} uses Roleypoly to manage self-assignable roles.

+
💖
+
+
+ Sign in with Discord +
+
+
+ } +} \ No newline at end of file diff --git a/UI/src/components/servers/index.js b/UI/src/components/servers/index.js index 300cf35..8811d0c 100644 --- a/UI/src/components/servers/index.js +++ b/UI/src/components/servers/index.js @@ -9,6 +9,7 @@ import Navigation from './Navigation' import RolePicker from '../role-picker' import RoleEditor from '../role-editor' import AddServer from '../add-server' +import Error404 from '../../pages/Error404' // import mockData from './mockData' @@ -23,6 +24,8 @@ const mapState = ({ servers, user, appState }) => { @connect(mapState) class Servers extends Component { get defaultPath () { + console.log(this.props.servers.toJS()) + const first = this.props.servers.first() if (first != null) { return first.get('id') @@ -35,18 +38,15 @@ class Servers extends Component { return
- - } /> - - - - - - - - - } /> - + + + + + + } /> + + +
} diff --git a/UI/src/pages/Error404.js b/UI/src/pages/Error404.js index 2c2706b..aeb6118 100644 --- a/UI/src/pages/Error404.js +++ b/UI/src/pages/Error404.js @@ -1,35 +1,14 @@ -import React, { Component, Fragment } from 'react' -import { Link } from 'react-router-dom' -import Scrollbars from 'react-custom-scrollbars' -import Typist from 'react-typist' -import moment from 'moment' +import React from 'react' import './landing.sass' -import discordLogo from './images/discord-logo.svg' -import RoleypolyDemo from '../components/demos/roleypoly' -import TypingDemo from '../components/demos/typing' -const Landing = ({ root = false }) => +const Error404 = ({ root = false }) =>
-

Self-assignable Discord roles for humans.

-

Ditch bot commands once and for all.

-
-
- Sign in with Discord -
-
- {/* Typist */} -
- -

Why are we stuck in the stupid ages?

-
- {/* role side */} -
- -

It's 2018. We can do better.

-
+

💔 g-gomen nasai

+

I'm not sure what page you were looking for 😢

-export default Landing + +export default Error404 diff --git a/UI/src/pages/ServerLanding.js b/UI/src/pages/ServerLanding.js deleted file mode 100644 index 2c2706b..0000000 --- a/UI/src/pages/ServerLanding.js +++ /dev/null @@ -1,35 +0,0 @@ -import React, { Component, Fragment } from 'react' -import { Link } from 'react-router-dom' -import Scrollbars from 'react-custom-scrollbars' -import Typist from 'react-typist' -import moment from 'moment' -import './landing.sass' -import discordLogo from './images/discord-logo.svg' -import RoleypolyDemo from '../components/demos/roleypoly' -import TypingDemo from '../components/demos/typing' - -const Landing = ({ root = false }) => -
-
-
-

Self-assignable Discord roles for humans.

-

Ditch bot commands once and for all.

-
-
- Sign in with Discord -
-
- {/* Typist */} -
- -

Why are we stuck in the stupid ages?

-
- {/* role side */} -
- -

It's 2018. We can do better.

-
-
-
-
-export default Landing diff --git a/UI/src/pages/index.js b/UI/src/pages/index.js index 81d4591..209a6ca 100644 --- a/UI/src/pages/index.js +++ b/UI/src/pages/index.js @@ -6,7 +6,6 @@ import './pages.sass' import WhyNoRoles from './WhyNoRoles' import Error404 from './Error404' export { default as Landing } from './Landing' -export { default as ServerLanding } from './ServerLanding' export { default as Error404 } from './Error404' const Pages = (props) => { diff --git a/UI/src/router/index.js b/UI/src/router/index.js index 0ec1bae..35426e1 100644 --- a/UI/src/router/index.js +++ b/UI/src/router/index.js @@ -7,7 +7,8 @@ import Servers from '../components/servers' import OauthCallback from '../components/oauth-callback' import OauthFlow from '../components/oauth-flow' import OauthBotFlow from '../components/oauth-bot-flow' -import Pages, { Landing, Error404, ServerLanding } from '../pages' +import Pages, { Landing, Error404 } from '../pages' +import ServerLanding from '../components/servers/ServerLanding' const aaa = (props) => (
{ JSON.stringify(props) }
) @@ -22,18 +23,15 @@ export default class AppRouter extends Component { } return - { (isLoggedIn) + { (isLoggedIn === true) // YES LOGGED IN - ? - - - + ? + // NOT LOGGED IN - : - - + : [, } />] + } {/* GENERAL ROUTES */}