auth: add slugs and auth redirects

This commit is contained in:
41666 2019-03-20 05:39:36 -05:00
parent f7d1f578ad
commit 1a7b042351
3 changed files with 79 additions and 10 deletions

View file

@ -57,11 +57,13 @@ export default (R: Router, $: AppContext) => {
})
R.get('/api/auth/redirect', async (ctx: Context) => {
const { r } = ctx.query
// check if already authed
if (await $.auth.isLoggedIn(ctx, { refresh: true })) {
return ctx.redirect('/')
return ctx.redirect(r || '/')
}
ctx.session.oauthRedirect = r
const url = $.discord.getAuthUrl(ksuid.randomSync().string)
if (ctx.query.url === '✔️') {
ctx.body = { url }
@ -72,11 +74,13 @@ export default (R: Router, $: AppContext) => {
})
R.get('/api/oauth/callback', async (ctx: Context) => {
const { code, state } = ctx.query
const { oauthRedirect: r } = ctx.session
delete ctx.session.oauthRedirect
if (await $.auth.isLoggedIn(ctx)) {
return ctx.redirect('/')
return ctx.redirect(r || '/')
}
const { code, state } = ctx.query
if (code == null) {
ctx.status = 400
return
@ -95,7 +99,7 @@ export default (R: Router, $: AppContext) => {
const tokens = await $.discord.getAuthToken(code)
const user = await $.discord.getUserFromToken(tokens.access_token)
$.auth.injectSessionFromOAuth(ctx, tokens, user.id)
return ctx.redirect('/')
return ctx.redirect(r || '/')
} catch (e) {
log.error('token and auth fetch failure', e)
ctx.status = 400

View file

@ -3,8 +3,17 @@ import * as React from 'react'
import Head from 'next/head'
import type { PageProps } from '../../types'
import SocialCards from '../../components/social-cards'
import redirect from '../../lib/redirect'
export default class Server extends React.Component<PageProps> {
static async getInitialProps (ctx: *, rpc: *, router: *) {
if (ctx.user == null) {
redirect(ctx, `/auth/login?r=${router.asPath}`)
}
ctx.robots = 'NOINDEX, NOFOLLOW'
}
render () {
return (
<div>

View file

@ -5,16 +5,27 @@ import MediaQuery from '../../kit/media'
import DiscordButton from '../../components/discord-button'
import RPC from '../../config/rpc'
import redirect from '../../lib/redirect'
import dynamic from 'next/dynamic'
import type { PageProps, ServerSlug } from '../../types'
type AuthLoginState = {
humanCode: string,
waiting: boolean
}
type AuthLoginProps = PageProps & {
redirect: ?string,
redirectSlug: ?ServerSlug
}
const Wrapper = styled.div`
display: flex;
justify-content: center;
padding-top: 3em;
width: 400px;
max-width: calc(98vw - 10px);
margin: 0 auto;
text-align: center;
${() => MediaQuery({
md: `
padding-top: 0;
@ -76,16 +87,60 @@ const HiderButton = styled.button`
pointer-events: none;
}
`
const SlugWrapper = styled.div`
padding-bottom: 2em;
text-align: center;
`
export default class AuthLogin extends React.Component<{}, AuthLoginState> {
const DiscordGuildPic = dynamic(() => import('../../components/discord-guild-pic'))
const StyledDGP = styled(DiscordGuildPic)`
border-radius: 100%;
border: 2px solid rgba(0,0,0,0.2);
height: 4em;
margin-top: 1em;
`
const ServerName = styled.span`
font-weight: bold;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
width: 370px;
display: block;
`
const Slug = (slug: ServerSlug) => <SlugWrapper>
<StyledDGP {...slug} />
<br />Hey there.<br /><ServerName>{slug.name}</ServerName> uses Roleypoly to manage its roles.
</SlugWrapper>
export default class AuthLogin extends React.Component<AuthLoginProps, AuthLoginState> {
state = {
humanCode: '',
waiting: false
}
static async getInitialProps (ctx, rpc) {
static async getInitialProps (ctx: *, rpc: typeof RPC, router: *) {
let { r } = (router.query: { r: string })
if (ctx.user != null) {
redirect(ctx, '/')
redirect(ctx, r || '/')
}
ctx.robots = 'NOINDEX, NOFOLLOW'
if (r != null) {
let redirectSlug = null
if (r.startsWith('/s/') && r !== '/s/add') {
redirectSlug = await rpc.getServerSlug(r.replace('/s/', ''))
}
return { redirect: r, redirectSlug }
}
}
componentDidMount () {
if (this.props.redirect != null) {
this.props.router.replace(this.props.router.pathname)
}
}
@ -98,9 +153,9 @@ export default class AuthLogin extends React.Component<{}, AuthLoginState> {
try {
const result = await RPC.checkAuthChallenge(this.state.humanCode)
if (result === true) {
redirect(null, '/')
redirect(null, this.props.redirect || '/')
}
} finally {
} catch (e) {
this.setState({ waiting: false })
}
}
@ -108,7 +163,8 @@ export default class AuthLogin extends React.Component<{}, AuthLoginState> {
render () {
return <Wrapper>
<div>
<DiscordButton href='/api/auth/redirect'>Sign in with Discord</DiscordButton>
{(this.props.redirectSlug != null) ? <Slug {...this.props.redirectSlug} /> : null}
<DiscordButton href={`/api/auth/redirect?r=${this.props.redirect || '/'}`}>Sign in with Discord</DiscordButton>
<Line />
<div>
<i>Or, send a DM to <b>roleypoly</b>#3712 saying: login</i>