Added authUpdated subscription

This commit is contained in:
Douglas Barone 2020-12-04 18:40:47 -04:00
parent 0f2df50daa
commit 05db879b27
8 changed files with 37 additions and 10 deletions

View File

@ -6,6 +6,8 @@ import { encodePassword } from '../utils/activedirectory/encodePassword'
import config from '../utils/activedirectory/config' import config from '../utils/activedirectory/config'
import jwt from 'jsonwebtoken' import jwt from 'jsonwebtoken'
import { pubsub, AUTH_UPDATED } from '../pubsub'
class User { class User {
constructor(username) { constructor(username) {
this.username = username this.username = username
@ -227,13 +229,17 @@ class User {
groups groups
} }
return prisma.user.upsert({ const dbUser = await prisma.user.upsert({
where: { where: {
sAMAccountName: user.sAMAccountName sAMAccountName: user.sAMAccountName
}, },
update: user, update: user,
create: user create: user
}) })
pubsub.publish(AUTH_UPDATED, { authUpdated: dbUser })
return dbUser
} }
/** /**

View File

@ -1,7 +1,8 @@
import { PubSub } from 'apollo-server' import { PubSub } from 'apollo-server'
const USER_PRESENCE_UPDATED = 'USER_PRESENCE_UPDATED' const USER_PRESENCE_UPDATED = 'USER_PRESENCE_UPDATED'
const AUTH_UPDATED = 'AUTH_UPDATED'
const pubsub = new PubSub() const pubsub = new PubSub()
export { pubsub, USER_PRESENCE_UPDATED } export { pubsub, USER_PRESENCE_UPDATED, AUTH_UPDATED }

View File

@ -1,10 +1,22 @@
import { pubsub, USER_PRESENCE_UPDATED } from '../pubsub' import { pubsub, USER_PRESENCE_UPDATED, AUTH_UPDATED } from '../pubsub'
import { withFilter } from 'apollo-server'
import { updateDevicesInfo } from '../utils/wifiUtils' import { validateToken } from '../utils/validateToken'
const Subscription = { const Subscription = {
userPresenceUpdated: { userPresenceUpdated: {
subscribe: () => pubsub.asyncIterator([USER_PRESENCE_UPDATED]) subscribe: () => pubsub.asyncIterator([USER_PRESENCE_UPDATED])
},
authUpdated: {
subscribe: withFilter(
() => pubsub.asyncIterator([AUTH_UPDATED]),
(payload, variables, context) => {
const { sAMAccountName } = validateToken(
context.connection.context.authorization
)
return payload.authUpdated.sAMAccountName == sAMAccountName
}
)
} }
} }

View File

@ -1,8 +1,8 @@
import { SchemaDirectiveVisitor } from 'apollo-server' import { SchemaDirectiveVisitor } from 'apollo-server'
import { defaultFieldResolver } from 'graphql' import { defaultFieldResolver } from 'graphql'
import jwt from 'jsonwebtoken'
import { User } from '../classes/User' import { User } from '../classes/User'
import { validateToken } from '../utils/validateToken'
class AuthDirective extends SchemaDirectiveVisitor { class AuthDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field, details) { visitFieldDefinition(field, details) {
@ -20,9 +20,8 @@ class AuthDirective extends SchemaDirectiveVisitor {
if (authorizationHeader) { if (authorizationHeader) {
const token = authorizationHeader.replace('Bearer ', '') const token = authorizationHeader.replace('Bearer ', '')
const { sAMAccountName, pwdLastSet } = jwt.verify( const { sAMAccountName, pwdLastSet } = validateToken(
token, authorizationHeader
process.env.JWT_SECRET
) )
const user = await new User(sAMAccountName).init() const user = await new User(sAMAccountName).init()

View File

@ -19,7 +19,7 @@ const server = new ApolloServer({
subscriptions: { subscriptions: {
onConnect: connectionParams => { onConnect: connectionParams => {
return { return {
authorization: connectionParams.headers.Authorization authorization: connectionParams.Authorization
} }
} }
}, },

View File

@ -48,6 +48,7 @@ const typeDefs = gql`
type Subscription { type Subscription {
userPresenceUpdated: Int! @auth(roles: ["watcher"]) userPresenceUpdated: Int! @auth(roles: ["watcher"])
authUpdated: User! @auth
} }
directive @auth(roles: [String!]) on FIELD_DEFINITION directive @auth(roles: [String!]) on FIELD_DEFINITION

View File

@ -1,6 +1,7 @@
import { promiseWrapper as AD } from 'activedirectory2' import { promiseWrapper as AD } from 'activedirectory2'
import config from './config' import config from './config'
// TODO: Refactor to instantiate in context creation function
const ad = new AD(config) const ad = new AD(config)
ad.checkBinding = async () => { ad.checkBinding = async () => {

View File

@ -0,0 +1,7 @@
import jwt from 'jsonwebtoken'
export function validateToken(authorizationHeader) {
const token = authorizationHeader.replace('Bearer ', '')
return jwt.verify(token, process.env.JWT_SECRET)
}