Server: Update resolver to use auth context

This commit is contained in:
Barry Low committed 2018-09-12 22:37:35 -07:00
1 parent 5731ec1957
commit 43f2bbceee
15 files changed
+2577 -145

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@ projects:
extensions:
endpoints:
dev1:
url: http://0.0.0.0:4000/graphql
url: http://localhost:4001/graphql
database:
schemaPath: src/generated/prisma.graphql
+1 -1
View File
@@ -1,6 +1,6 @@
FROM mhart/alpine-node:8
ENV PORT=4000
ENV PORT=4001
RUN mkdir -p /var/www/app && \
mkdir -p /var/www/app/node_modules
+2 -1
View File
@@ -30,6 +30,7 @@ type Team {
slug: String! @unique
profile: TeamProfile
members: [TeamMembers!]! @relation (name: "TeamMembers", onDelete: SET_NULL)
owner: String!
wallet: Wallet
fb: [FinancialBeings!]! @relation (name: "TeamFinancialBeing", onDelete: SET_NULL)
status: [TeamStatus!]!
@@ -59,7 +60,7 @@ type TeamMembers {
type Member {
id: ID! @unique
nickname: String
alias: String
team: TeamMembers @relation (name: "MemberOnTeam", onDelete: SET_NULL)
authId: String! @unique
visible: Boolean! @default(value: true)
+19
View File
@@ -0,0 +1,19 @@
version: '3'
services:
api:
image: aateamapi-dev:v1
build:
context: .
dockerfile: ./Dockerfile
env_file: ./.env
container_name: aateamapi
tty: true
stdin_open: true
volumes:
- ./:/var/www/app
- /var/www/app/node_modules
working_dir: /var/www/app
restart: always
command: node -r dotenv/config src/index.js
ports:
- "4001:4001"
-19
View File
@@ -27,24 +27,5 @@ services:
POSTGRES_PASSWORD: prisma
volumes:
- postgres:/var/lib/postgresql/data
node:
image: aateamapi-dev:v1
build:
context: .
dockerfile: ./Dockerfile
depends_on:
- prisma
env_file: ./.env
container_name: aateamapi
tty: true
stdin_open: true
volumes:
- ./:/var/www/app
- /var/www/app/node_modules
working_dir: /var/www/app
restart: always
command: node -r dotenv/config src/index.js
ports:
- "4000:4000"
volumes:
postgres:
+51 -69
View File
@@ -568,7 +568,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -614,7 +614,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -923,7 +923,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -1462,7 +1462,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -1492,9 +1492,9 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"config-chain": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz",
"integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
"integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
"dev": true,
"requires": {
"ini": "^1.3.4",
@@ -1640,7 +1640,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -4997,7 +4997,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -5366,7 +5366,7 @@
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -6371,14 +6371,14 @@
"dev": true
},
"prisma": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-1.15.3.tgz",
"integrity": "sha512-95s0Kk8PtptrVhp4ajXPd7A7QrbWdCEyZ/nnvcz0Sz9nzufYYZfBjxgibUyoaNs/XL0KXtiibQIdZhpWIJgOhw==",
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-1.16.0.tgz",
"integrity": "sha512-8jZYCrkd1xjy+JJbQi81f8PBOLe8LLWwSu0fK0cqekm3FeafBd8xk5b0RWcIsHyVd6ypKCQt3tnZEMVzmbKrdQ==",
"dev": true,
"requires": {
"fs-extra": "^5.0.0",
"prisma-cli-core": "1.0.75",
"prisma-cli-engine": "1.0.78",
"prisma-cli-core": "1.0.76",
"prisma-cli-engine": "1.0.79",
"semver": "^5.4.1",
"source-map-support": "^0.4.18"
},
@@ -6497,9 +6497,9 @@
}
},
"prisma-cli-core": {
"version": "1.0.75",
"resolved": "https://registry.npmjs.org/prisma-cli-core/-/prisma-cli-core-1.0.75.tgz",
"integrity": "sha512-DiH686w2u9aiz4RoNX3T0XgGzeai8IrXX/Qsocam+lKtBB63aupqCxbj6kp16sNoiXhDPzI2Zx/Hwm0GG9sUhw==",
"version": "1.0.76",
"resolved": "https://registry.npmjs.org/prisma-cli-core/-/prisma-cli-core-1.0.76.tgz",
"integrity": "sha512-HtHn/RM2GlJi23KoIXHoboP97aC54SYDqr7B4uT/80JP6A6nQp5HLt4sJgNfKapaHFZVzXYM7M3LEfGq3tgQbw==",
"dev": true,
"requires": {
"adm-zip": "^0.4.7",
@@ -6533,9 +6533,9 @@
"opn": "^5.1.0",
"pause": "^0.1.0",
"portfinder": "^1.0.13",
"prisma-db-introspection": "0.0.45",
"prisma-db-introspection": "0.0.46",
"prisma-json-schema": "0.0.4",
"prisma-yml": "1.0.90",
"prisma-yml": "1.0.96",
"scuid": "^1.0.2",
"semver": "^5.4.1",
"sillyname": "^0.1.0",
@@ -6599,12 +6599,12 @@
}
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz",
"integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==",
"dev": true,
"requires": {
"ms": "2.0.0"
"ms": "^2.1.1"
}
},
"dotenv": {
@@ -6693,7 +6693,7 @@
},
"graphql-import": {
"version": "0.4.5",
"resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz",
"resolved": "http://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz",
"integrity": "sha512-G/+I08Qp6/QGTb9qapknCm3yPHV0ZL7wbaalWFpxsfR8ZhZoTBe//LsbsCKlbALQpcMegchpJhpTSKiJjhaVqQ==",
"dev": true,
"requires": {
@@ -6766,12 +6766,6 @@
"regex-cache": "^0.4.2"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"prisma-json-schema": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/prisma-json-schema/-/prisma-json-schema-0.0.4.tgz",
@@ -6779,9 +6773,9 @@
"dev": true
},
"prisma-yml": {
"version": "1.0.90",
"resolved": "https://registry.npmjs.org/prisma-yml/-/prisma-yml-1.0.90.tgz",
"integrity": "sha512-i5qMN/p1YvLV931YgfJtUAaHO7nOL07oW/EqQ1AixBGRi9nB21TpZGy9b50TwunaMt8LfVYB5ER82338qrJA5g==",
"version": "1.0.96",
"resolved": "https://registry.npmjs.org/prisma-yml/-/prisma-yml-1.0.96.tgz",
"integrity": "sha512-w3XGzJHUq5pwBoFy/amkGOcTDj4XoHh8UFUUUZcHo5fSyoF8AWeRTu1yWINaPVGxbcmpwKNetntAW4ijiq7M5g==",
"dev": true,
"requires": {
"ajv": "5",
@@ -6828,9 +6822,9 @@
}
},
"prisma-cli-engine": {
"version": "1.0.78",
"resolved": "https://registry.npmjs.org/prisma-cli-engine/-/prisma-cli-engine-1.0.78.tgz",
"integrity": "sha512-chtmecxBgXPQUzvDS0U/R+pHZ/nzV1ksO+OiKr98kT7dBR9QJQbRG0v/j+zoIW4vdR9eyIaXy5i+dW8HU8XnDg==",
"version": "1.0.79",
"resolved": "https://registry.npmjs.org/prisma-cli-engine/-/prisma-cli-engine-1.0.79.tgz",
"integrity": "sha512-CdEIJs4ld1IiQQt2CFFPmeDypN4Ct4sTgmFODVjJix790mpEtxMagzCcA+mhfnRL65P6xiHn76Gdxbz60GyYBA==",
"dev": true,
"requires": {
"@heroku/linewrap": "^1.0.0",
@@ -6873,7 +6867,7 @@
"memfs": "^2.5.3",
"opn": "^5.1.0",
"prisma-json-schema": "0.0.4",
"prisma-yml": "1.0.90",
"prisma-yml": "1.0.96",
"raven": "2.3.0",
"replaceall": "^0.1.6",
"rwlockfile": "^1.4.8",
@@ -6890,12 +6884,12 @@
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz",
"integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==",
"dev": true,
"requires": {
"ms": "2.0.0"
"ms": "^2.1.1"
}
},
"dotenv": {
@@ -6931,12 +6925,6 @@
"through": "^2.3.6"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"prisma-json-schema": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/prisma-json-schema/-/prisma-json-schema-0.0.4.tgz",
@@ -6944,9 +6932,9 @@
"dev": true
},
"prisma-yml": {
"version": "1.0.90",
"resolved": "https://registry.npmjs.org/prisma-yml/-/prisma-yml-1.0.90.tgz",
"integrity": "sha512-i5qMN/p1YvLV931YgfJtUAaHO7nOL07oW/EqQ1AixBGRi9nB21TpZGy9b50TwunaMt8LfVYB5ER82338qrJA5g==",
"version": "1.0.96",
"resolved": "https://registry.npmjs.org/prisma-yml/-/prisma-yml-1.0.96.tgz",
"integrity": "sha512-w3XGzJHUq5pwBoFy/amkGOcTDj4XoHh8UFUUUZcHo5fSyoF8AWeRTu1yWINaPVGxbcmpwKNetntAW4ijiq7M5g==",
"dev": true,
"requires": {
"ajv": "5",
@@ -7002,9 +6990,9 @@
}
},
"prisma-db-introspection": {
"version": "0.0.45",
"resolved": "https://registry.npmjs.org/prisma-db-introspection/-/prisma-db-introspection-0.0.45.tgz",
"integrity": "sha512-tOdv4mBFZLVds1Wst92l2iarmzlxwFo/EFHs4kW1P0rR2My7BoxRgV0HSZy9xvo9gbU3P8e5JEZofMNrS+5v+g==",
"version": "0.0.46",
"resolved": "https://registry.npmjs.org/prisma-db-introspection/-/prisma-db-introspection-0.0.46.tgz",
"integrity": "sha512-/b7evS9b5xKS7UrcOERkCmV+IWC6OAgFtInFsvdwn4MeLEaVbkOfzRakdOo+t2gb+N7Yy8Eey9eKYgB5jiJAbA==",
"dev": true,
"requires": {
"ajv": "5",
@@ -7029,12 +7017,12 @@
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz",
"integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==",
"dev": true,
"requires": {
"ms": "2.0.0"
"ms": "^2.1.1"
}
},
"dotenv": {
@@ -7043,12 +7031,6 @@
"integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=",
"dev": true
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"prisma-json-schema": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/prisma-json-schema/-/prisma-json-schema-0.0.1.tgz",
@@ -7608,7 +7590,7 @@
"dependencies": {
"commander": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
"dev": true,
"requires": {
@@ -8196,7 +8178,7 @@
},
"table": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz",
"resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz",
"integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==",
"dev": true,
"requires": {
@@ -8257,7 +8239,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -8522,7 +8504,7 @@
},
"buffer": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz",
"resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz",
"integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=",
"dev": true,
"requires": {
@@ -9105,7 +9087,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
+1 -1
View File
@@ -22,6 +22,6 @@
"devDependencies": {
"graphql-cli": "^2.16.5",
"npm-run-all": "4.1.3",
"prisma": "^1.14.0"
"prisma": "^1.16.0"
}
}
+34 -10
View File
@@ -1,6 +1,5 @@
const _get = require('lodash.get')
const validateAndParseIdToken = require('./helpers/validateAndParseIdToken')
const createMember = require('./index')
const { validateIdToken } = require('./validateIdToken')
const memberLocationOnContext = 'request.member'
const bearerAccessToken = 'request.headers.authorization'
@@ -8,11 +7,29 @@ const bearerAccessToken = 'request.headers.authorization'
const ctxMember = ctx => _get(ctx, memberLocationOnContext)
const ctxToken = ctx => _get(ctx, bearerAccessToken)
const createMember = async (ctx, idToken, info) => {
console.log('createMember', idToken)
const member = await ctx.db.mutation.upsertMember({
where: {
authId: idToken.sub,
},
create: {
authId: idToken.sub,
alias: idToken.nickname
},
update: {
authId: idToken.sub,
alias: idToken.nickname
}
}, info)
return member
}
const isLoggedIn = async ctx => {
let member = ctxMember(ctx, memberLocationOnContext)
let token = ctxToken(ctx, bearerAccessToken)
let memberToken
console.log('isLoggedIn: ', member, token)
if (!member && token) {
let scheme, credentials
const tokenParts = token.split(' ')
@@ -24,21 +41,28 @@ const isLoggedIn = async ctx => {
if (/^Bearer$/i.test(scheme)) {
token = credentials
//verify token
console.log('isLoggedIn2 : ', token)
try {
memberToken = await validateAndParseIdToken(token)
const auth0id = memberToken.sub
memberToken = await validateIdToken(token)
const authId = memberToken.sub
console.log('isLoggedIn3 : ', await authId, ctx.db.query.member)
exists = await ctx.db.query.member({ where: { authId: authId } })
console.log('isLoggedIn4 : ', await exists, createMember )
if (!member && exists === null) {
member = await createMember(ctx, memberToken).then(res => {
console.log('isLoggedIn5 : ', res)
return res
})
member = await ctx.db.query.member({ where: { auth0id } })
if (!member) {
member = await createMember(ctx, memberToken)
return member
}
return member
} catch (err) {
memberToken = false
}
}
}
console.log('isLoggedIn5 : ', await member)
if (!member) {
throw new Error(`Not logged in`)
}
+2 -2
View File
@@ -7,7 +7,7 @@ const jwks = jwksClient({
jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
})
const validateParseIdToken = idToken =>
const validateIdToken = idToken =>
new Promise((resolve, reject) => {
const { header, payload } = jwt.decode(idToken, { complete: true })
if (!header || !header.kid || !payload) reject(new Error('Invalid Token'))
@@ -25,4 +25,4 @@ const validateParseIdToken = idToken =>
})
})
module.exports = validateParseIdToken
module.exports = { validateIdToken }
File diff suppressed because it is too large. Load diff
+55 -29
View File
@@ -1,3 +1,4 @@
require('dotenv').config();
const { GraphQLServer } = require('graphql-yoga')
const {
Prisma,
@@ -8,15 +9,39 @@ const { makeExecutableSchema } = require('graphql-tools')
const { importSchema } = require('graphql-import')
const { checkJwt } = require('./auth/middleware/jwt')
const { getMember } = require('./auth/middleware/getMember')
const validateParseIdToken = require('./auth/helpers/validate-parse-id-token')
const { directiveResolvers } = require('./auth-directives')
const { validateIdToken } = require('./auth/validateIdToken')
const { directiveResolvers } = require('./auth/authDirectives')
const createMember = async function (ctx, info, idToken) {
console.log('createMember', idToken)
const member = await ctx.db.mutation.upsertMember({
where: {
authId: idToken.sub,
},
create: {
authId: idToken.sub,
alias: idToken.nickname
},
update: {
authId: idToken.sub,
alias: idToken.nickname
}
}, info)
return member
}
const ctxMember = ctx => ctx.request.member
const resolvers = {
Query: {
async member(parent, { auth0id }, ctx, info) {
return ctx.db.query.member({ where: { auth0id } }, info)
async member(parent, arg, ctx, info) {
console.log('member: ', parent, arg)
return ctx.db.query.member({ where: { authId: arg.authId } }, info)
},
async currentMember(parent, args, ctx, info) {
console.log('currentMember: ', ctx.request.res.req.user)
const authId = ctx.request.res.req.user.sub
return ctx.db.query.member({ where: { authId } }, info)
},
teams(parent, args, ctx, info) {
return ctx.db.query.teamsConnection({},
@@ -59,7 +84,7 @@ const resolvers = {
return ctx.db.query.team({ where: { name: name } }, `{ name }`)
},
async teamByOwner(parent, { ownerId }, ctx, info) {
return ctx.db.query.teamsConnection({where: { owner: { auth0id: ownerId }}},
return ctx.db.query.teamsConnection({where: { owner: { authId: ownerId }}},
`{
edges {
node {
@@ -72,7 +97,7 @@ const resolvers = {
motto
}
owner {
auth0id
authId
nickname
visible
profile {
@@ -95,28 +120,27 @@ const resolvers = {
},
async owner(parent, args, ctx, info) {
console.log('resolver.query.owner ctx: ', ctxMember(ctx))
return ctx.db.query.member({ where: { id: ctxMember(ctx).auth0id } }, info)
return ctx.db.query.member({ where: { id: ctxMember(ctx).authId } }, info)
.catch((res) => {
console.log('createTeam error: ', res)
const errors = res.graphQLErrors.map((error) => {
return error.message
})
})
},
members: forwardTo('db')
}
},
Mutation: {
async authenticate(parent, { idToken }, ctx, info) {
let memberToken = null
try {
memberToken = await validateAndParseIdToken(idToken)
memberToken = await validateIdToken(idToken)
console.log('authenticate.memberToken: ', await memberToken)
} catch (err) {
console.log('authenticat.validateAndParseIdToken err: ', err)
console.log('authenticat.validateIdToken err: ', err)
throw new Error(err.message)
}
const auth0id = memberToken.sub
let member = await ctx.db.query.member({ where: { auth0id } }, info)
const authId = memberToken.sub
let member = await ctx.db.query.member({ where: { authId } }, info)
if (!member) {
try {
@@ -124,7 +148,6 @@ const resolvers = {
} catch (error) {
throw new Error(error.message)
}
}
}
return member
},
@@ -133,15 +156,12 @@ const resolvers = {
data: {
name: name,
slug: slug,
owner: {connect:{auth0id: owner}},
members: {create: {role: 'OWNER', member: {connect: {auth0id: owner}}}}
owner: owner
}
}, info)
.catch((res) => {
console.log('createTeam error: ', res)
const errors = res.graphQLErrors.map((error) => {
return error.message
})
.catch((err) => {
console.log('createTeam error: ', err)
return err
})
},
async deleteTeam(parent, { id }, ctx, info) {
@@ -176,25 +196,30 @@ const server = new GraphQLServer({
context: req => ({
...req,
db
})
}),
})
server.express.post(
server.express.use(
server.options.endpoint,
checkJwt,
(err, req, res, next) => {
console.log('checkJwt: ', err, req.user)
if (err) return res.status(401).send(err.message)
next()
}
)
server.express.post(server.options.endpoint, (req, res, done) =>
server.express.post(server.options.endpoint, (err, req, res, done) => {
console.log('getMember: ', err, req.user)
getMember(req, res, done, db)
)
})
const whitelist = [
'http://localhost:1337',
'http://0.0.0.0:5000'
'http://localhost:3000',
'http://localhost:3001',
'http://localhost:3002',
'http://localhost:4000',
'http://localhost:4002'
]
const corsOptionsDelegate = (req, callback) => {
var corsOptions
@@ -207,12 +232,13 @@ const corsOptionsDelegate = (req, callback) => {
}
const options = {
port: 4001,
cors: corsOptionsDelegate,
endpoint: '/graphql',
subscriptions: '/graphql',
playground: '/playground'
}
server.start(options, () => console.log(`Server is running on http://localhost:4000${server.options.endpoint}`))
server.start(options, () => console.log(`Server is running on http://localhost:4001${server.options.endpoint}`))
module.exports= { createPrismaMember: createPrismaMember }
module.exports= { createMember }
@@ -12,24 +12,37 @@ type Query {
teamById(teamId: String!): Team
teamByOwner(ownerId: String!): TeamConnection
owner: Member @isAuthenticated
member(auth0id: String!): Member @isAuthenticated
currentMember: Member @isAuthenticated
member(authId: String!): Member @isAuthenticated
}
type Mutation {
authenticate(idToken: String!): Member
createTeam(name: String!, slug: String, owner: String): Team @isAuthenticated
deleteTeam(id: ID!): Team @isAuthenticated @isOwner(type: "Team")
updateProfile(data: MemberProfileInput): Member @isAuthenticated
}
input MemberProfileInput {
auth0id: String!
nickname: String!
anonymous: Boolean
visible: Boolean
avatar: String
email: String
repo: String
bio: String
status: String
authId: String!
alias: String!
}
fragment MemberInfo on Member {
id
authId
alias
isActive
profile {
...MemberProfileInfo
}
}
fragment MemberProfileInfo on MemberProfile {
firstName
lastName
email
avatar
role {
name
}
}
+2 -1
View File
@@ -3,7 +3,8 @@ import Footer from './footer'
import Callback from './callback'
import Home from './home'
import Dashboard from './dashboard'
import Teams from './teams'
import { theme, globalStyles } from './theme'
export { NavBar, Footer, Callback, Home, Dashboard, theme, globalStyles }
export { NavBar, Footer, Callback, Home, Dashboard, Teams, theme, globalStyles }
+53
View File
@@ -0,0 +1,53 @@
import React from 'react'
import PropTypes from 'prop-types'
import CssBaseline from '@material-ui/core/CssBaseline'
import Typography from '@material-ui/core/Typography'
import { withStyles } from '@material-ui/core/styles'
const styles = theme => ({
'@global': {
body: {
backgroundColor: theme.palette.common.white
}
},
layout: {
width: 'auto',
marginLeft: theme.spacing.unit * 3,
marginRight: theme.spacing.unit * 3,
[theme.breakpoints.up(900 + theme.spacing.unit * 3 * 2)]: {
width: 900,
marginLeft: 'auto',
marginRight: 'auto'
}
},
heroContent: {
maxWidth: 600,
margin: '0 auto',
padding: `${theme.spacing.unit * 8}px 0 ${theme.spacing.unit * 6}px`
}
})
const Home = ({ classes }) => (
<React.Fragment>
<CssBaseline />
<main className={classes.layout}>
<div className={classes.heroContent}>
<Typography
variant='display3'
align='center'
color='textPrimary'
gutterBottom
>
Teams
</Typography>
</div>
</main>
</React.Fragment>
)
Home.propTypes = {
classes: PropTypes.object.isRequired
}
export default withStyles(styles)(Home)
+5
View File
@@ -0,0 +1,5 @@
# Code Styling and Formatting
```
npm install --save-dev eslint-config-standard eslint-config-standard-react eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node eslint-plugin-react
```