logging in and logging out

This commit is contained in:
Sendou
2019-05-31 02:21:08 +03:00
parent fd36d54b9b
commit f8fb6ae419
9 changed files with 529 additions and 53 deletions

107
index.js
View File

@@ -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
View 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
View File

@@ -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",

View File

@@ -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"

View File

@@ -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}

View File

@@ -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>
)

View File

@@ -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) {

View File

@@ -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"}}>

View File

@@ -0,0 +1,11 @@
import { gql } from 'apollo-boost'
export const userLean = gql`
{
user {
username
avatar
discord_id
}
}
`