Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group subscription #382

Merged
merged 15 commits into from
Sep 28, 2024
585 changes: 508 additions & 77 deletions graphql/resolvers.js

Large diffs are not rendered by default.

53 changes: 44 additions & 9 deletions graphql/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const typeDefs = gql`
leader: [ID!]!
"""
leader: User!
showAdminName: Boolean!
followers: [User!]!
route: [Location!]!
landmarks: [Landmark!]!
Expand Down Expand Up @@ -68,6 +69,7 @@ const typeDefs = gql`
"""
name: String
email: String
isVerified: Boolean
location: Location
beacons: [Beacon!]!
groups: [Group!]!
Expand Down Expand Up @@ -99,11 +101,39 @@ const typeDefs = gql`
type Query {
beacon(id: ID!): Beacon!
group(id: ID!): Group!
nearbyBeacons(location: LocationInput!): [Beacon!]!
nearbyBeacons(id: ID!, location: LocationInput!, radius: Float!): [Beacon!]!
groups(page: Int, pageSize: Int): [Group!]!
beacons(groupId: ID!, page: Int, pageSize: Int): [Beacon!]!
filterBeacons(id: ID!, type: String): [Beacon!]!
me: User
hello: String
}

input oAuthInput {
email: String
name: String
}

type UpdatedGroupPayload {
groupId: ID!
newUser: User
newBeacon: Beacon
deletedBeacon: Beacon
updatedBeacon: Beacon
}

type BeaconLocationsPayload {
userSOS: User
route: [Location]
updatedUser: User
landmark: Landmark
}

type JoinLeaveBeaconPayload {
newfollower: User
inactiveuser: User
}

type Mutation {
"""
if start time not supplied, default is Date.now
Expand All @@ -114,21 +144,26 @@ const typeDefs = gql`
"""
one of ID or credentials required (ID for anon)
"""
login(id: ID, credentials: AuthPayload): String
login(id: ID, credentials: AuthPayload): String!
sendVerificationCode: String!
completeVerification: User!
removeMember(groupId: ID!, memberId: ID!): User!
oAuth(userInput: oAuthInput): String
changeShortcode(groupId: ID!): Group!
joinBeacon(shortcode: String!): Beacon!
updateBeaconLocation(id: ID!, location: LocationInput!): Beacon!
updateUserLocation(id: ID!, location: LocationInput!): User!
updateUserLocation(id: ID!, location: LocationInput!): User
changeLeader(beaconID: ID!, newLeaderID: ID!): Beacon!
changeBeaconDuration(newExpiresAt: Float!, beaconID: ID!): Beacon!
rescheduleHike(newExpiresAt: Float!, newStartsAt: Float!, beaconID: ID!): Beacon!
createGroup(group: GroupInput): Group!
joinGroup(shortcode: String!): Group!
deleteBeacon(id: ID!): Boolean!
sos(id: ID!): User!
}

type Subscription {
beaconLocation(id: ID!): Location
userLocation(id: ID!): User
beaconJoined(id: ID!): User
groupJoined(groupID: ID!): User
beaconLocations(id: ID!): BeaconLocationsPayload!
JoinLeaveBeacon(id: ID!): JoinLeaveBeaconPayload!
groupUpdate(groupIds: [ID!]): UpdatedGroupPayload!
}

schema {
Expand Down
11 changes: 4 additions & 7 deletions index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { ApolloServer } from "apollo-server-express";
import { applyMiddleware } from "graphql-middleware";
import { makeExecutableSchema } from "graphql-tools";
import mongoose from "mongoose";

import typeDefs from "./graphql/schema.js";
import resolvers from "./graphql/resolvers.js";
import { User } from "./models/user.js";
Expand All @@ -15,9 +14,7 @@ import pubsub from "./pubsub.js";

const server = new ApolloServer({
schema: applyMiddleware(makeExecutableSchema({ typeDefs, resolvers }), permissions),
// schema: makeExecutableSchema({ typeDefs, resolvers }), // to temp disable shield on dev
context: async ({ req, connection }) => {
// initialize context even if it comes from subscription connection
if (connection) {
return { user: connection.context.user, pubsub };
}
Expand All @@ -32,14 +29,15 @@ const server = new ApolloServer({
onConnect: async connectionParams => {
console.log("Client connected");
const authorization = connectionParams["Authorization"];
// add user to connection context

if (authorization) {
try {
const decoded = jwt.verify(authorization.replace("Bearer ", ""), process.env.JWT_SECRET);
console.log("decoded: ", decoded);
const user = await User.findById(decoded.sub).populate("beacons");
return { user };
} catch (err) {
console.log(err);
throw new Error("Invalid token!");
}
}
Expand Down Expand Up @@ -70,12 +68,11 @@ app.get("/j/:shortcode", async (_req, res) => {

server.applyMiddleware({ app });
const httpServer = http.createServer(app);

server.installSubscriptionHandlers(httpServer);

const uri = process.env.DB;
const options = { useNewUrlParser: true, useUnifiedTopology: true };
mongoose
.connect(uri, options)
.connect(process.env.DB)
.then(() =>
httpServer.listen(
{ port: 4000 },
Expand Down
6 changes: 3 additions & 3 deletions models/beacon.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
const mongoose = require("mongoose");

const LocationSchema = require("./location.js");
const { UserSchema } = require("./user.js");

const { Schema, model } = mongoose;

const beaconSchema = new Schema(
Expand All @@ -12,9 +10,11 @@ const beaconSchema = new Schema(
startsAt: { type: Date, default: Date.now },
expiresAt: { type: Date, required: true },
leader: { type: Schema.Types.ObjectId, required: true, ref: "User" },
// member location
location: LocationSchema,
followers: [UserSchema],
followers: { type: [Schema.Types.ObjectId], ref: "User", default: [] },
route: [LocationSchema],
// remove when leave user
landmarks: { type: [Schema.Types.ObjectId], ref: "Landmark" },
group: { type: Schema.Types.ObjectId, ref: "Group" },
},
Expand Down
4 changes: 2 additions & 2 deletions models/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const groupSchema = new Schema(
title: String,
shortcode: { type: String, required: true, unique: true },
leader: { type: Schema.Types.ObjectId, required: true, ref: "User" },
members: { type: [Schema.Types.ObjectId], ref: "User" },
beacons: { type: [Schema.Types.ObjectId], ref: "Beacon" },
members: { type: [Schema.Types.ObjectId], ref: "User", default: [] },
beacons: { type: [Schema.Types.ObjectId], ref: "Beacon", default: [] },
},
{
timestamps: true,
Expand Down
3 changes: 2 additions & 1 deletion models/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const locationSchema = new Schema(
lon: String,
},
{
timestamps: true,
_id: false,
timestamps: false,
}
);

Expand Down
5 changes: 3 additions & 2 deletions models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ const UserSchema = new Schema(
email: String,
password: String,
// store most recent location
isVerified: { type: Boolean, default: false },
location: LocationSchema,
beacons: { type: [Schema.Types.ObjectId], ref: "Beacon" },
groups: { type: [Schema.Types.ObjectId], ref: "Group" },
beacons: { type: [Schema.Types.ObjectId], ref: "Beacon", default: [] },
groups: { type: [Schema.Types.ObjectId], ref: "Group", default: [] },
},
{
timestamps: true,
Expand Down
Loading