mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-25 20:50:14 -05:00
logging in and logging out
This commit is contained in:
107
index.js
107
index.js
@@ -2,19 +2,64 @@ require('dotenv').config()
|
||||
const { ApolloServer, UserInputError, AuthenticationError, gql } = require('apollo-server-express')
|
||||
const mongoose = require('mongoose')
|
||||
const express = require('express')
|
||||
const session = require('express-session')
|
||||
const bodyParser = require('body-parser')
|
||||
const cookieParser = require('cookie-parser')
|
||||
const uuid = require('node-uuid')
|
||||
const axios = require('axios')
|
||||
const cors = require('cors')
|
||||
const passport = require('passport')
|
||||
const DiscordStrategy = require('passport-discord').Strategy
|
||||
const Placement = require('./models/placement')
|
||||
const Player = require('./models/player')
|
||||
const Maplist = require('./models/maplist')
|
||||
const Link = require('./models/link')
|
||||
//const User = require('./models/user')
|
||||
const User = require('./models/user')
|
||||
const jwt = require('jsonwebtoken')
|
||||
const path = require('path')
|
||||
|
||||
mongoose.set('useFindAndModify', false)
|
||||
mongoose.set('useCreateIndex', true)
|
||||
|
||||
passport.use(new DiscordStrategy({
|
||||
clientID: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET,
|
||||
callbackURL: 'http://localhost:3001/auth/discord/callback',
|
||||
scope: ['identify', 'connections']
|
||||
},
|
||||
function(accessToken, refreshToken, profile, cb) {
|
||||
const userToSave = {
|
||||
username: profile.username,
|
||||
discriminator: profile.discriminator,
|
||||
avatar: profile.avatar,
|
||||
discord_id: profile.id
|
||||
}
|
||||
for (var i = 0; i < profile.connections.length; i++) {
|
||||
const connection = profile.connections[i]
|
||||
if (connection.visibility === 1 && connection.verified) {
|
||||
if (connection.type === 'twitch') {
|
||||
userToSave.twitch_name = connection.name
|
||||
} else if (connection.type === 'twitter') {
|
||||
userToSave.twitter_name = connection.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
User.updateOne({discord_id: userToSave.discord_id}, userToSave, {upsert: true}, function(err, user) {
|
||||
return cb(err, userToSave)
|
||||
})
|
||||
}))
|
||||
|
||||
passport.serializeUser(function(user, done) {
|
||||
done(null, user.discord_id)
|
||||
})
|
||||
|
||||
passport.deserializeUser(function(discord_id, done) {
|
||||
User.findOne({discord_id}, function(err, user) {
|
||||
done(err, user)
|
||||
})
|
||||
})
|
||||
|
||||
let rotationData = {timestamp: 0}
|
||||
|
||||
console.log('connecting to MongoDB')
|
||||
@@ -28,12 +73,6 @@ mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, dbName: "prod
|
||||
})
|
||||
|
||||
const typeDefs = gql`
|
||||
type User {
|
||||
id: ID!
|
||||
username: String!
|
||||
passwordHash: String!
|
||||
}
|
||||
|
||||
type Player {
|
||||
id: ID!
|
||||
name: String!
|
||||
@@ -105,6 +144,15 @@ const typeDefs = gql`
|
||||
type: LinkType!
|
||||
}
|
||||
|
||||
type User {
|
||||
username: String!
|
||||
discriminator: String!
|
||||
avatar: String
|
||||
discord_id: String!
|
||||
twitch_name: String!
|
||||
twitter_name: String!
|
||||
}
|
||||
|
||||
type Token {
|
||||
value: String!
|
||||
}
|
||||
@@ -128,6 +176,7 @@ const typeDefs = gql`
|
||||
maplists: [Maplist!]!
|
||||
rotationData: String
|
||||
links: [Link!]!
|
||||
user: User
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
@@ -424,11 +473,15 @@ const resolvers = {
|
||||
links: (root, args) => {
|
||||
return Link
|
||||
.find({})
|
||||
.sort({ "title": "asc" })
|
||||
.catch(e => {
|
||||
throw new UserInputError(e.message, {
|
||||
invalidArgs: args,
|
||||
})
|
||||
})
|
||||
},
|
||||
user: (root, args, ctx) => {
|
||||
return ctx.user
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,28 +489,46 @@ const resolvers = {
|
||||
const server = new ApolloServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
context: async ({ req }) => {
|
||||
const auth = req ? req.headers.authorization : null
|
||||
if (auth && auth.toLowerCase().startsWith('bearer ')) {
|
||||
const decodedToken = jwt.verify(
|
||||
auth.substring(7), process.env.JWT_SECRET
|
||||
)
|
||||
const currentUser = await User.findById(decodedToken.id)
|
||||
return { currentUser }
|
||||
}
|
||||
context: ({ req }) => {
|
||||
return { user: req.user }
|
||||
}
|
||||
})
|
||||
|
||||
const app = express()
|
||||
app.use(cors())
|
||||
server.applyMiddleware({ app })
|
||||
|
||||
app.use(cors())
|
||||
app.use(express.static('build'))
|
||||
//app.use(cookieParser(process.env.SESSION_SECRET)) probably not needed but will remove later
|
||||
//app.use(bodyParser.urlencoded({ extended: false }))
|
||||
|
||||
app.use(session({
|
||||
secret: process.env.SESSION_SECRET,
|
||||
resave: false,
|
||||
saveUninitialized: false
|
||||
}))
|
||||
|
||||
app.use(passport.initialize())
|
||||
app.use(passport.session())
|
||||
|
||||
app.get('/auth/discord', passport.authenticate('discord'))
|
||||
|
||||
app.get('/auth/discord/callback', passport.authenticate('discord', {
|
||||
failureRedirect: '/404'
|
||||
}), function(req, res) {
|
||||
res.redirect('/u/' + req.user.discord_id) // Successful auth
|
||||
})
|
||||
|
||||
app.get('/logout', function(req, res){
|
||||
req.logout()
|
||||
res.redirect('/')
|
||||
})
|
||||
|
||||
app.get('*', (req, res) => {
|
||||
res.sendFile(path.resolve(__dirname, 'build', 'index.html'))
|
||||
})
|
||||
|
||||
server.applyMiddleware({ app })
|
||||
|
||||
const PORT = process.env.PORT || 3001
|
||||
app.listen({ port: PORT }, () => {
|
||||
console.log(`Server running on http://localhost:${PORT}${server.graphqlPath}`)
|
||||
|
||||
12
models/user.js
Normal file
12
models/user.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const mongoose = require('mongoose')
|
||||
|
||||
const userSchema = new mongoose.Schema({
|
||||
username: {type: String, required: true},
|
||||
discriminator: {type: String, required: true},
|
||||
avatar: {type: String},
|
||||
discord_id: {type: String, required: true},
|
||||
twitch_name: {type: String},
|
||||
twitter_name: {type: String}
|
||||
})
|
||||
|
||||
module.exports = mongoose.model('User', userSchema)
|
||||
347
package-lock.json
generated
347
package-lock.json
generated
@@ -120,9 +120,9 @@
|
||||
}
|
||||
},
|
||||
"@types/express-serve-static-core": {
|
||||
"version": "4.16.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.4.tgz",
|
||||
"integrity": "sha512-x/8h6FHm14rPWnW2HP5likD/rsqJ3t/77OWx2PLxym0hXbeBWQmcPyHmwX+CtCQpjIfgrUdEoDFcLPwPZWiqzQ==",
|
||||
"version": "4.16.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.6.tgz",
|
||||
"integrity": "sha512-8wr3CA/EMybyb6/V8qvTRKiNkPmgUA26uA9XWD6hlA0yFDuqi4r2L0C2B0U2HAYltJamoYJszlkaWM31vrKsHg==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/range-parser": "*"
|
||||
@@ -315,6 +315,27 @@
|
||||
"express": "^4.0.0",
|
||||
"graphql-subscriptions": "^1.0.0",
|
||||
"graphql-tools": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"apollo-server-express": {
|
||||
"version": "2.4.8",
|
||||
"resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.4.8.tgz",
|
||||
"integrity": "sha512-i60l32mfVe33jnKDPNYgUKUKu4Al0xEm2HLOSMgtJ9Wbpe/MbOx5X8M5F27fnHYdM+G5XfAErsakAyRGnQJ48Q==",
|
||||
"requires": {
|
||||
"@apollographql/graphql-playground-html": "^1.6.6",
|
||||
"@types/accepts": "^1.3.5",
|
||||
"@types/body-parser": "1.17.0",
|
||||
"@types/cors": "^2.8.4",
|
||||
"@types/express": "4.16.1",
|
||||
"accepts": "^1.3.5",
|
||||
"apollo-server-core": "2.4.8",
|
||||
"body-parser": "^1.18.3",
|
||||
"cors": "^2.8.4",
|
||||
"graphql-subscriptions": "^1.0.0",
|
||||
"graphql-tools": "^4.0.0",
|
||||
"type-is": "^1.6.16"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"apollo-server-caching": {
|
||||
@@ -367,9 +388,9 @@
|
||||
"integrity": "sha512-wY/YE3iJVMYC+WYIf8QODBjIP4jhI+oc7kiYo9mrz7LdYPKAgxr/he+NteGcqn/0Ea9K5/ZFTGJDbEstSMeP8g=="
|
||||
},
|
||||
"apollo-server-express": {
|
||||
"version": "2.4.8",
|
||||
"resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.4.8.tgz",
|
||||
"integrity": "sha512-i60l32mfVe33jnKDPNYgUKUKu4Al0xEm2HLOSMgtJ9Wbpe/MbOx5X8M5F27fnHYdM+G5XfAErsakAyRGnQJ48Q==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.5.0.tgz",
|
||||
"integrity": "sha512-2gd3VWIqji2jyDYMTTqKzVU4/znjEjugtLUmPgVl5SoBvJSMTsO7VgJv+roBubZGDK8jXXUEXr2a33RtIeHe4g==",
|
||||
"requires": {
|
||||
"@apollographql/graphql-playground-html": "^1.6.6",
|
||||
"@types/accepts": "^1.3.5",
|
||||
@@ -377,12 +398,173 @@
|
||||
"@types/cors": "^2.8.4",
|
||||
"@types/express": "4.16.1",
|
||||
"accepts": "^1.3.5",
|
||||
"apollo-server-core": "2.4.8",
|
||||
"apollo-server-core": "2.5.0",
|
||||
"body-parser": "^1.18.3",
|
||||
"cors": "^2.8.4",
|
||||
"graphql-subscriptions": "^1.0.0",
|
||||
"graphql-tools": "^4.0.0",
|
||||
"type-is": "^1.6.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollographql/apollo-tools": {
|
||||
"version": "0.3.7",
|
||||
"resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.3.7.tgz",
|
||||
"integrity": "sha512-+ertvzAwzkYmuUtT8zH3Zi6jPdyxZwOgnYaZHY7iLnMVJDhQKWlkyjLMF8wyzlPiEdDImVUMm5lOIBZo7LkGlg==",
|
||||
"requires": {
|
||||
"apollo-env": "0.5.1"
|
||||
}
|
||||
},
|
||||
"apollo-cache-control": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.6.0.tgz",
|
||||
"integrity": "sha512-66aCF6MHe0/FdD3knphwTv6CCIdb1ZxrMsiRpxP474qqyYVe2jAwBu6aJBn4emffZHZ7i6gp9dY6cPHThjnbKA==",
|
||||
"requires": {
|
||||
"apollo-server-env": "2.3.0",
|
||||
"graphql-extensions": "0.6.0"
|
||||
}
|
||||
},
|
||||
"apollo-datasource": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.4.0.tgz",
|
||||
"integrity": "sha512-6QkgnLYwQrW0qv+yXIf617DojJbGmza2XJXUlgnzrGGhxzfAynzEjaLyYkc8rYS1m82vjrl9EOmLHTcnVkvZAQ==",
|
||||
"requires": {
|
||||
"apollo-server-caching": "0.4.0",
|
||||
"apollo-server-env": "2.3.0"
|
||||
}
|
||||
},
|
||||
"apollo-engine-reporting": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-1.1.0.tgz",
|
||||
"integrity": "sha512-Dj0BwgcluHL0QVUaquhAoYoLX9Z4DRP/n2REcIwO8d2iy52r+1wN5QqZLx97dEFh7CjhNjTWeysJzc8XMWKa1Q==",
|
||||
"requires": {
|
||||
"apollo-engine-reporting-protobuf": "0.3.0",
|
||||
"apollo-graphql": "^0.2.1-alpha.1",
|
||||
"apollo-server-core": "2.5.0",
|
||||
"apollo-server-env": "2.3.0",
|
||||
"async-retry": "^1.2.1",
|
||||
"graphql-extensions": "0.6.0"
|
||||
}
|
||||
},
|
||||
"apollo-engine-reporting-protobuf": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.3.0.tgz",
|
||||
"integrity": "sha512-PYowpx/E+TJT/8nKpp3JmJuKh3x1SZcxDF6Cquj0soV205TUpFFCZQMi91i5ACiEp2AkYvM/GDBIrw+rfIwzTg==",
|
||||
"requires": {
|
||||
"protobufjs": "^6.8.6"
|
||||
}
|
||||
},
|
||||
"apollo-env": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.5.1.tgz",
|
||||
"integrity": "sha512-fndST2xojgSdH02k5hxk1cbqA9Ti8RX4YzzBoAB4oIe1Puhq7+YlhXGXfXB5Y4XN0al8dLg+5nAkyjNAR2qZTw==",
|
||||
"requires": {
|
||||
"core-js": "^3.0.1",
|
||||
"node-fetch": "^2.2.0",
|
||||
"sha.js": "^2.4.11"
|
||||
}
|
||||
},
|
||||
"apollo-graphql": {
|
||||
"version": "0.2.1-register.1",
|
||||
"resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.2.1-register.1.tgz",
|
||||
"integrity": "sha512-Z2LOuvYomC9CN9K+mpFVcVQu6Ml5PIJlV+YOkGzFq73xeqWg1InxHqI3eEdCEhxTJq6H8rlWT8ATrMS+4sIhqw==",
|
||||
"requires": {
|
||||
"apollo-env": "0.4.1-register.1",
|
||||
"lodash.sortby": "^4.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"apollo-env": {
|
||||
"version": "0.4.1-register.1",
|
||||
"resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.4.1-register.1.tgz",
|
||||
"integrity": "sha512-fg1US7YZ6yW1N0tFq8g4HpCR3eJZmI+rIiHDiknYN9D1MTjvwYdmXYhi7VaPvQ21hV5nMRvfBUMqYXjP+6FsGQ==",
|
||||
"requires": {
|
||||
"core-js": "3.0.0-beta.13",
|
||||
"node-fetch": "^2.2.0",
|
||||
"sha.js": "^2.4.11"
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.0.0-beta.13",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.0-beta.13.tgz",
|
||||
"integrity": "sha512-16Q43c/3LT9NyePUJKL8nRIQgYWjcBhjJSMWg96PVSxoS0PeE0NHitPI3opBrs9MGGHjte1KoEVr9W63YKlTXQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"apollo-server-caching": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.4.0.tgz",
|
||||
"integrity": "sha512-GTOZdbLhrSOKYNWMYgaqX5cVNSMT0bGUTZKV8/tYlyYmsB6ey7l6iId3Q7UpHS6F6OR2lstz5XaKZ+T3fDfPzQ==",
|
||||
"requires": {
|
||||
"lru-cache": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"apollo-server-core": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.5.0.tgz",
|
||||
"integrity": "sha512-7hyQ/Rt0hC38bUfxMQmLNHDBIGEBykFWo9EO0W+3o/cno/SqBKd1KKichrABVv+v+SCvZAUutX6gYS5l3G+ULQ==",
|
||||
"requires": {
|
||||
"@apollographql/apollo-tools": "^0.3.6-alpha.1",
|
||||
"@apollographql/graphql-playground-html": "^1.6.6",
|
||||
"@types/ws": "^6.0.0",
|
||||
"apollo-cache-control": "0.6.0",
|
||||
"apollo-datasource": "0.4.0",
|
||||
"apollo-engine-reporting": "1.1.0",
|
||||
"apollo-server-caching": "0.4.0",
|
||||
"apollo-server-env": "2.3.0",
|
||||
"apollo-server-errors": "2.3.0",
|
||||
"apollo-server-plugin-base": "0.4.0",
|
||||
"apollo-tracing": "0.6.0",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"graphql-extensions": "0.6.0",
|
||||
"graphql-subscriptions": "^1.0.0",
|
||||
"graphql-tag": "^2.9.2",
|
||||
"graphql-tools": "^4.0.0",
|
||||
"graphql-upload": "^8.0.2",
|
||||
"sha.js": "^2.4.11",
|
||||
"subscriptions-transport-ws": "^0.9.11",
|
||||
"ws": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"apollo-server-env": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.3.0.tgz",
|
||||
"integrity": "sha512-WIwlkCM/gir0CkoYWPMTCH8uGCCKB/aM074U1bKayvkFOBVO2VgG5x2kgsfkyF05IMQq2/GOTsKhNY7RnUEhTA==",
|
||||
"requires": {
|
||||
"node-fetch": "^2.1.2",
|
||||
"util.promisify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"apollo-server-errors": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.3.0.tgz",
|
||||
"integrity": "sha512-rUvzwMo2ZQgzzPh2kcJyfbRSfVKRMhfIlhY7BzUfM4x6ZT0aijlgsf714Ll3Mbf5Fxii32kD0A/DmKsTecpccw=="
|
||||
},
|
||||
"apollo-server-plugin-base": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.4.0.tgz",
|
||||
"integrity": "sha512-iD7ARNtwnvHGd1EMPK0CuodM8d8hgDvFwTfIDzJY04QIQ6/KrBFaWhnCXJsy+HMb47GovwBbq67IK6eb2WJgBg=="
|
||||
},
|
||||
"apollo-tracing": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.6.0.tgz",
|
||||
"integrity": "sha512-OpYPHVBgcQ/HT2WLXJQWwhilzR1rrl01tZeMU2N7yinsp/oyKngF5aUSMtuvX1k/T3abilQo+w10oAQlBCGdPA==",
|
||||
"requires": {
|
||||
"apollo-server-env": "2.3.0",
|
||||
"graphql-extensions": "0.6.0"
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.3.tgz",
|
||||
"integrity": "sha512-PWZ+ZfuaKf178BIAg+CRsljwjIMRV8MY00CbZczkR6Zk5LfkSkjGoaab3+bqRQWVITNZxQB7TFYz+CFcyuamvA=="
|
||||
},
|
||||
"graphql-extensions": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.6.0.tgz",
|
||||
"integrity": "sha512-SshzmbD68fHXRv2q3St29olMOxHDLQ5e9TOh+Tz2BYxinrfhjFaPNcEefiK/vF295wW827Y58bdO11Xmhf8J+Q==",
|
||||
"requires": {
|
||||
"@apollographql/apollo-tools": "^0.3.6-alpha.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"apollo-server-plugin-base": {
|
||||
@@ -410,19 +592,19 @@
|
||||
}
|
||||
},
|
||||
"apollo-utilities": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.2.1.tgz",
|
||||
"integrity": "sha512-Zv8Udp9XTSFiN8oyXOjf6PMHepD4yxxReLsl6dPUy5Ths7jti3nmlBzZUOxuTWRwZn0MoclqL7RQ5UEJN8MAxg==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.0.tgz",
|
||||
"integrity": "sha512-wQjV+FdWcTWmWUFlChG5rS0vHKy5OsXC6XlV9STRstQq6VbXANwHy6DHnTEQAfLXWAbNcPgBu+nBUpR3dFhwrA==",
|
||||
"requires": {
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"ts-invariant": "^0.2.1",
|
||||
"ts-invariant": "^0.4.0",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"ts-invariant": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.2.1.tgz",
|
||||
"integrity": "sha512-Z/JSxzVmhTo50I+LKagEISFJW3pvPCqsMWLamCTX8Kr3N5aMrnGOqcflbe5hLUzwjvgPfnLzQtHZv0yWQ+FIHg==",
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.2.tgz",
|
||||
"integrity": "sha512-PTAAn8lJPEdRBJJEs4ig6MVZWfO12yrFzV7YaPslmyhG7+4MA279y4BXT3f72gXeVl0mC1aAWq2rMX4eKTWU/Q==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
@@ -572,6 +754,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"base64url": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
|
||||
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="
|
||||
},
|
||||
"binary-extensions": {
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
|
||||
@@ -674,6 +861,11 @@
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz",
|
||||
"integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg=="
|
||||
},
|
||||
"btoa": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
|
||||
"integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g=="
|
||||
},
|
||||
"buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
@@ -853,6 +1045,15 @@
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
|
||||
},
|
||||
"cookie-parser": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz",
|
||||
"integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==",
|
||||
"requires": {
|
||||
"cookie": "0.3.1",
|
||||
"cookie-signature": "1.0.6"
|
||||
}
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
@@ -1293,6 +1494,41 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"express-session": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.1.tgz",
|
||||
"integrity": "sha512-pWvUL8Tl5jUy1MLH7DhgUlpoKeVPUTe+y6WQD9YhcN0C5qAhsh4a8feVjiUXo3TFhIy191YGZ4tewW9edbl2xQ==",
|
||||
"requires": {
|
||||
"cookie": "0.3.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~2.0.0",
|
||||
"on-headers": "~1.0.2",
|
||||
"parseurl": "~1.3.2",
|
||||
"safe-buffer": "5.1.2",
|
||||
"uid-safe": "~2.1.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend-shallow": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
|
||||
@@ -2847,9 +3083,14 @@
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.5.0.tgz",
|
||||
"integrity": "sha512-YuZKluhWGJwCcUu4RlZstdAxr8bFfOVHakc1mplwHkk8J+tqM1Y5yraYvIUpeX8aY7+crCwiELJq7Vl0o0LWXw=="
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||
},
|
||||
"node-uuid": {
|
||||
"version": "1.4.8",
|
||||
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
|
||||
"integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc="
|
||||
},
|
||||
"nodemon": {
|
||||
"version": "1.19.0",
|
||||
@@ -2893,6 +3134,11 @@
|
||||
"path-key": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"oauth": {
|
||||
"version": "0.9.15",
|
||||
"resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
|
||||
"integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@@ -2974,6 +3220,11 @@
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"on-headers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
|
||||
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
|
||||
},
|
||||
"p-finally": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||
@@ -3003,6 +3254,45 @@
|
||||
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
|
||||
"dev": true
|
||||
},
|
||||
"passport": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz",
|
||||
"integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=",
|
||||
"requires": {
|
||||
"passport-strategy": "1.x.x",
|
||||
"pause": "0.0.1"
|
||||
}
|
||||
},
|
||||
"passport-discord": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/passport-discord/-/passport-discord-0.1.3.tgz",
|
||||
"integrity": "sha512-o8+KiQrV63DCJvYVceyVJgyFhHxqOPlcxaiB8Hlrrm0uq83KfQOMPUcXal0pao5Qx8ZeOH/RBJEbJV9aB0F/hw==",
|
||||
"requires": {
|
||||
"passport-oauth2": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"passport-oauth2": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz",
|
||||
"integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==",
|
||||
"requires": {
|
||||
"base64url": "3.x.x",
|
||||
"oauth": "0.9.x",
|
||||
"passport-strategy": "1.x.x",
|
||||
"uid2": "0.0.x",
|
||||
"utils-merge": "1.x.x"
|
||||
}
|
||||
},
|
||||
"passport-oauth2-refresh": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/passport-oauth2-refresh/-/passport-oauth2-refresh-1.1.0.tgz",
|
||||
"integrity": "sha512-UsmDntTlEKj8GAME/u6hvgTgq/WC/1lh9wGKs7QEf5/e+pBo9dnphJ1qLfmwFck21lz3wHHHiPFJrihLkFSaXg=="
|
||||
},
|
||||
"passport-strategy": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
|
||||
"integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
|
||||
},
|
||||
"path-dirname": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
|
||||
@@ -3032,6 +3322,11 @@
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"pause": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
|
||||
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
|
||||
},
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
@@ -3109,6 +3404,11 @@
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"random-bytes": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||
"integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
|
||||
@@ -3788,6 +4088,19 @@
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"uid-safe": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
|
||||
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
|
||||
"requires": {
|
||||
"random-bytes": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"uid2": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
|
||||
"integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
|
||||
},
|
||||
"undefsafe": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
|
||||
|
||||
13
package.json
13
package.json
@@ -11,14 +11,23 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"apollo-server": "^2.4.8",
|
||||
"apollo-server-express": "^2.4.8",
|
||||
"apollo-server-express": "^2.5.0",
|
||||
"axios": "^0.18.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"btoa": "^1.2.1",
|
||||
"cookie-parser": "^1.4.4",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^7.0.0",
|
||||
"express-session": "^1.16.1",
|
||||
"graphql": "^14.2.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mongoose": "^5.5.5",
|
||||
"mongoose-unique-validator": "^2.0.3"
|
||||
"mongoose-unique-validator": "^2.0.3",
|
||||
"node-fetch": "^2.6.0",
|
||||
"node-uuid": "^1.4.8",
|
||||
"passport": "^0.4.0",
|
||||
"passport-discord": "^0.1.3",
|
||||
"passport-oauth2-refresh": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^1.19.0"
|
||||
|
||||
10
react-ui/src/components/Misc/Links.js
vendored
10
react-ui/src/components/Misc/Links.js
vendored
@@ -30,7 +30,7 @@ const Links = ({ setMenuSelection }) => {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<List.Item key={l.title}>
|
||||
<List.Item key={l.title} style={{'padding': '6px'}}>
|
||||
<List.Header size='small' as='a' href={l.url}>{l.title}</List.Header>
|
||||
<List.Description>
|
||||
{l.description}
|
||||
@@ -40,7 +40,7 @@ const Links = ({ setMenuSelection }) => {
|
||||
})}
|
||||
</List>
|
||||
</div>
|
||||
<div style={{'paddingTop': '25px'}}>
|
||||
<div style={{'paddingTop': '20px'}}>
|
||||
<Header as='h1'>
|
||||
<Icon name='book' />
|
||||
<Header.Content>Guides</Header.Content>
|
||||
@@ -51,7 +51,7 @@ const Links = ({ setMenuSelection }) => {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<List.Item key={l.title}>
|
||||
<List.Item key={l.title} style={{'padding': '6px'}}>
|
||||
<List.Header size='small' as='a' href={l.url}>{l.title}</List.Header>
|
||||
<List.Description>
|
||||
{l.description}
|
||||
@@ -61,7 +61,7 @@ const Links = ({ setMenuSelection }) => {
|
||||
})}
|
||||
</List>
|
||||
</div>
|
||||
<div style={{'paddingTop': '25px'}}>
|
||||
<div style={{'paddingTop': '20px'}}>
|
||||
<Header as='h1'>
|
||||
<Icon name='folder open' />
|
||||
<Header.Content>Misc</Header.Content>
|
||||
@@ -72,7 +72,7 @@ const Links = ({ setMenuSelection }) => {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<List.Item key={l.title}>
|
||||
<List.Item key={l.title} style={{'padding': '6px'}}>
|
||||
<List.Header size='small' as='a' href={l.url}>{l.title}</List.Header>
|
||||
<List.Description>
|
||||
{l.description}
|
||||
|
||||
60
react-ui/src/components/Misc/MainMenu.js
vendored
60
react-ui/src/components/Misc/MainMenu.js
vendored
@@ -1,10 +1,58 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Menu, Segment } from 'semantic-ui-react'
|
||||
import { Menu, Segment, Button, Icon, Image, Popup } from 'semantic-ui-react'
|
||||
import { useQuery } from 'react-apollo-hooks'
|
||||
import { userLean } from '../../graphql/queries/userLean'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { memCakes } from '../../utils/lists'
|
||||
|
||||
const MainMenu = withRouter(({ history, menuSelection, setMenuSelection }) => {
|
||||
const [memCakePic, setMemCakePic] = useState(memCakes[Math.floor(Math.random()*memCakes.length)])
|
||||
const { data, error, loading } = useQuery(userLean)
|
||||
|
||||
const logIn = () => {
|
||||
if (loading) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (!data.user || error) {
|
||||
return (
|
||||
<Menu.Item>
|
||||
<a href='/auth/discord'>
|
||||
<Button
|
||||
style={{'color': '#7289DA'}}
|
||||
inverted
|
||||
>
|
||||
Login via Discord
|
||||
</Button>
|
||||
</a>
|
||||
</Menu.Item>
|
||||
)
|
||||
}
|
||||
|
||||
const user = data.user
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Menu.Item>
|
||||
<span style={{"paddingRight": "3px"}}>{user.username}</span>
|
||||
<Image src={`https://cdn.discordapp.com/avatars/${user.discord_id}/${user.avatar}.png`} avatar />
|
||||
<span style={{"paddingLeft": "10px"}}>
|
||||
<Popup
|
||||
position='bottom center'
|
||||
flowing
|
||||
hoverable
|
||||
trigger={<Icon name='log out' circular />}
|
||||
>
|
||||
<a href='/logout'>
|
||||
<Button secondary>Log Out</Button>
|
||||
</a>
|
||||
</Popup>
|
||||
</span>
|
||||
</Menu.Item>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Segment inverted>
|
||||
<Menu inverted secondary stackable>
|
||||
@@ -14,10 +62,7 @@ const MainMenu = withRouter(({ history, menuSelection, setMenuSelection }) => {
|
||||
<Menu.Item
|
||||
name='maplists'
|
||||
active={menuSelection === 'maplists'}
|
||||
onClick={() => {
|
||||
history.push('/maps')
|
||||
setMenuSelection('maplists')
|
||||
}}
|
||||
onClick={() => { history.push('/maps') }}
|
||||
/>
|
||||
<Menu.Item
|
||||
name='rotations'
|
||||
@@ -40,8 +85,11 @@ const MainMenu = withRouter(({ history, menuSelection, setMenuSelection }) => {
|
||||
<Menu.Item
|
||||
name='links'
|
||||
active={menuSelection === 'links'}
|
||||
onClick={() => { history.push('links') }}
|
||||
onClick={() => { history.push('/links') }}
|
||||
/>
|
||||
<Menu.Menu position='right'>
|
||||
{logIn()}
|
||||
</Menu.Menu>
|
||||
</Menu>
|
||||
</Segment>
|
||||
)
|
||||
|
||||
@@ -15,8 +15,8 @@ const MapListGenerator = ({ setMenuSelection }) => {
|
||||
const [ amountToGenerate, setAmountToGenerate ] = useState(12)
|
||||
const [ generatedMaps, setGeneratedMaps ] = useState([])
|
||||
const [ generationType, setGenerationType] = useState('rotate')
|
||||
const [copySuccess, setCopySuccess] = useState('');
|
||||
const textAreaRef = useRef(null);
|
||||
const [copySuccess, setCopySuccess] = useState('')
|
||||
const textAreaRef = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
|
||||
18
react-ui/src/components/Tools/Rotations.js
vendored
18
react-ui/src/components/Tools/Rotations.js
vendored
@@ -218,11 +218,23 @@ const Rotations = ({ setMenuSelection }) => {
|
||||
const seconds = timeUntil % 3600 % 60
|
||||
let header = 'Current'
|
||||
if (hours >= 2) {
|
||||
header = `In ${hours} hours ${minutes} minutes (${new Date(r.start_time * 1000).toLocaleString('en-GB')})`
|
||||
if (minutes === 1) {
|
||||
header = `In ${hours} hours ${minutes} minute (${new Date(r.start_time * 1000).toLocaleString('en-GB')})`
|
||||
} else {
|
||||
header = `In ${hours} hours ${minutes} minutes (${new Date(r.start_time * 1000).toLocaleString('en-GB')})`
|
||||
}
|
||||
} else if (hours > 0) {
|
||||
header = `In ${hours} hours ${minutes} minutes ${seconds} seconds`
|
||||
if (minutes === 1) {
|
||||
header = `In ${hours} hour ${minutes} minute ${seconds} seconds`
|
||||
} else {
|
||||
header = `In ${hours} hour ${minutes} minutes ${seconds} seconds`
|
||||
}
|
||||
} else if (minutes > 0) {
|
||||
header = `In ${minutes} minutes ${seconds} seconds`
|
||||
if (minutes === 1) {
|
||||
header = `In ${hours} hour ${minutes} minute ${seconds} seconds`
|
||||
} else {
|
||||
header = `In ${minutes} minutes ${seconds} seconds`
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div key={r.start_time} style={{"paddingTop": "25px"}}>
|
||||
|
||||
11
react-ui/src/graphql/queries/userLean.js
vendored
Normal file
11
react-ui/src/graphql/queries/userLean.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { gql } from 'apollo-boost'
|
||||
|
||||
export const userLean = gql`
|
||||
{
|
||||
user {
|
||||
username
|
||||
avatar
|
||||
discord_id
|
||||
}
|
||||
}
|
||||
`
|
||||
Reference in New Issue
Block a user