Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0fc6266
setup script will now ask for superAdmin email
AdityaRaimec22 Dec 23, 2023
14615db
asked changes
AdityaRaimec22 Dec 23, 2023
5e5e23d
Update setup.ts
AdityaRaimec22 Dec 23, 2023
c6eea57
new commit
AdityaRaimec22 Dec 23, 2023
b13b0d7
Merge branch 'branch1' of https://github.com/AdityaRaimec22/talawa-ap…
AdityaRaimec22 Dec 23, 2023
73abe20
new commit
AdityaRaimec22 Dec 23, 2023
698f51c
new commit
AdityaRaimec22 Dec 23, 2023
1da5e70
new commit
AdityaRaimec22 Dec 24, 2023
8e8908f
new commit
AdityaRaimec22 Dec 25, 2023
de82a5e
new commit
AdityaRaimec22 Dec 25, 2023
7add1e1
new commit
AdityaRaimec22 Dec 25, 2023
677a434
new commit
AdityaRaimec22 Dec 25, 2023
87c99b1
new commit
AdityaRaimec22 Dec 25, 2023
c5845fe
Merge pull request #1 from AdityaRaimec22/branch3
AdityaRaimec22 Dec 25, 2023
4078cea
Merge branch 'PalisadoesFoundation:develop' into develop
AdityaRaimec22 Dec 26, 2023
78cd00d
Merge branch 'PalisadoesFoundation:develop' into develop
AdityaRaimec22 Jan 6, 2024
090d11b
redis commit
AdityaRaimec22 Jan 6, 2024
5aa73c7
new commit
AdityaRaimec22 Jan 16, 2024
e7659ff
new commit
AdityaRaimec22 Jan 16, 2024
fd129f3
new commit
AdityaRaimec22 Jan 17, 2024
e855984
new commit
AdityaRaimec22 Jan 17, 2024
1459a1c
new commit
AdityaRaimec22 Jan 18, 2024
6051aba
Merge branch 'PalisadoesFoundation:develop' into develop
AdityaRaimec22 Jan 18, 2024
1819e58
new commit
AdityaRaimec22 Jan 18, 2024
17b9e5a
new commit
AdityaRaimec22 Jan 18, 2024
9f76172
new commit
AdityaRaimec22 Jan 18, 2024
709147b
solved merge conflicts
AdityaRaimec22 Jan 18, 2024
9a5aade
solved merge conflicts
AdityaRaimec22 Jan 18, 2024
57219ba
solved merge conflicts
AdityaRaimec22 Jan 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const config: CodegenConfig = {

EventAttendee: "../models/EventAttendee#InterfaceEventAttendee",

Family: "../models/Family#InterfaceFamily",

Feedback: "../models/Feedback#InterfaceFeedback",

// File: '../models/File#InterfaceFile',
Expand Down
20 changes: 20 additions & 0 deletions sample_data/family.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"_id": "60f18f31b7e5c4a2a4c3f905",
"title": "Smith Family",
"users": [
"64378abd85008f171cf2990d",
"65378abd85008f171cf2990d",
"66378abd85008f171cf2990d"
]
},
{
"_id": "60f18f31b7e5c4a2a4c3f906",
"title": "Johnson Family",
"users": [
"66378abd85008f171cf2990d",
"65378abd85008f171cf2990d",
"64378abd85008f171cf2990d"
]
}
]
18 changes: 18 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@ type ExtendSession {
refreshToken: String!
}

type Family {
_id: ID!
title: String!
users: [User!]!
}

type Feedback {
_id: ID!
createdAt: DateTime!
Expand Down Expand Up @@ -486,6 +492,7 @@ type Mutation {
addUserCustomData(dataName: String!, dataValue: Any!, organizationId: ID!): UserCustomData!
addUserImage(file: String!): User!
addUserToGroupChat(chatId: ID!, userId: ID!): GroupChat!
addUserToFamily(familyId: ID!, userId: ID!): Family!
adminRemoveEvent(eventId: ID!): Event!
adminRemoveGroup(groupId: ID!): GroupChat!
assignUserTag(input: ToggleUserTagAssignInput!): User
Expand All @@ -500,6 +507,7 @@ type Mutation {
createDonation(amount: Float!, nameOfOrg: String!, nameOfUser: String!, orgId: ID!, payPalId: ID!, userId: ID!): Donation!
createEvent(data: EventInput): Event!
createGroupChat(data: createGroupChatInput!): GroupChat!
createFamilyGroup(data: createFamilyGroupInput): Family!
createMember(input: UserAndOrganizationInput!): Organization!
createMessageChat(data: MessageChatInput!): MessageChat!
createOrganization(data: OrganizationInput, file: String): Organization!
Expand Down Expand Up @@ -528,6 +536,8 @@ type Mutation {
removeDirectChat(chatId: ID!, organizationId: ID!): DirectChat!
removeEvent(id: ID!): Event!
removeEventAttendee(data: EventAttendeeInput!): User!
removeEventProject(id: ID!): EventProject!
removeFamily(familyId: ID!): Family!
removeGroupChat(chatId: ID!): GroupChat!
removeMember(data: UserAndOrganizationInput!): Organization!
removeOrganization(id: ID!): User!
Expand All @@ -537,6 +547,7 @@ type Mutation {
removeSampleOrganization: Boolean!
removeUserCustomData(organizationId: ID!): UserCustomData!
removeUserFromGroupChat(chatId: ID!, userId: ID!): GroupChat!
removeUserFromFamily(familyId: ID!, userId: ID!): Family!
removeUserImage: User!
removeUserTag(id: ID!): UserTag
revokeRefreshTokenForUser: Boolean!
Expand Down Expand Up @@ -810,6 +821,7 @@ type Query {
event(id: ID!): Event
eventsByOrganization(id: ID, orderBy: EventOrderByInput): [Event]
eventsByOrganizationConnection(first: Int, orderBy: EventOrderByInput, skip: Int, where: EventWhereInput): [Event!]!
family(id: ID!): [Family]!
getAdvertisements: [Advertisement]
getDonationById(id: ID!): Donation!
getDonationByOrgId(orgId: ID!): [Donation]
Expand Down Expand Up @@ -973,6 +985,7 @@ type User {
email: EmailAddress!
employmentStatus: EmploymentStatus
eventAdmin: [Event]
Family: [Family]
firstName: String!
gender: Gender
image: String
Expand Down Expand Up @@ -1144,4 +1157,9 @@ input createGroupChatInput {
organizationId: ID!
title: String!
userIds: [ID!]!
}

input createFamilyGroupInput {
title: String!
userIds: [ID!]!
}
12 changes: 12 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,24 @@ export const LENGTH_VALIDATION_ERROR = {
PARAM: "stringValidation",
};

export const FAMILY_MIN_MEMBERS_ERROR_CODE = {
MESSAGE: "Error: Members in the family must be more than one",
CODE: "membersInFamilyLessThanOne",
PARAM: "membersInFamilyLessThanOne",
};

export const REGEX_VALIDATION_ERROR = {
MESSAGE: "Error: Entered value must be a valid string",
CODE: "string.notValid",
PARAM: "stringValidation",
};

export const FAMILY_NOT_FOUND_ERROR = {
MESSAGE: "Error: Family Not Found",
CODE: "familyNotFound",
PARAM: "familyNotFound",
};

export const USER_NOT_AUTHORIZED_SUPERADMIN = {
MESSAGE: "Error: Current user must be a SUPERADMIN",
CODE: "role.notValid.superadmin",
Expand Down
2 changes: 1 addition & 1 deletion src/middleware/isAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,4 @@ export const isAuth = (request: Request): InterfaceAuthData => {
authData.userId = decodedToken.userId;

return authData;
};
};
47 changes: 47 additions & 0 deletions src/models/Family.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { PopulatedDoc, Types, Document, Model } from "mongoose";
import { Schema, model, models } from "mongoose";
import type { InterfaceUser } from "./User";
/**
* This is an interface that represents a database(MongoDB) document for Family.
*/

export interface InterfaceFamily {
_id: Types.ObjectId;
title: string;
users: PopulatedDoc<InterfaceUser & Document>[];
}

/**
* @param title - Name of the Family (type: String)
* Description: Name of the Family.
*/

/**
* @param users - Members associated with the Family (type: String)
* Description: Members associated with the Family.
*/
const FamilySchema = new Schema({
title: {
type: String,
required: true,
},
users: [
{
type: Schema.Types.ObjectId,
ref: "User",
required: true,
},
],
});

// $2a$12$usOiKueW0FsZfpUuGNrAQuxvM.AB/nCOsHLdpE0liAcUr5PHOuc2K

//token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlblZlcnNpb24iOjcsInVzZXJJZ

const familyModel = (): Model<InterfaceFamily> =>
model<InterfaceFamily>("Family", FamilySchema);

// This syntax is needed to prevent Mongoose OverwriteModelError while running tests.
export const Family = (models.Family || familyModel()) as ReturnType<
typeof familyModel
>;
15 changes: 14 additions & 1 deletion src/models/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import validator from "validator";
import type { InterfaceEvent } from "./Event";
import type { InterfaceMembershipRequest } from "./MembershipRequest";
import type { InterfaceOrganization } from "./Organization";
import type { InterfaceFamily } from "./Family";
/**
* This is an interface that represents a database(MongoDB) document for User.
*/
Expand Down Expand Up @@ -35,6 +36,7 @@ export interface InterfaceUser {
gender: string;
image: string | undefined | null;
joinedOrganizations: PopulatedDoc<InterfaceOrganization & Document>[];
Family: PopulatedDoc<InterfaceFamily & Document> | null;
lastName: string;
maritalStatus: string;
membershipRequests: PopulatedDoc<InterfaceMembershipRequest & Document>[];
Expand Down Expand Up @@ -131,6 +133,10 @@ const userSchema = new Schema(
birthDate: {
type: Date,
},
createdAt: {
type: Date,
default: Date.now,
},
createdOrganizations: [
{
type: Schema.Types.ObjectId,
Expand Down Expand Up @@ -197,6 +203,10 @@ const userSchema = new Schema(
ref: "Organization",
},
],
Family: {
type: Schema.Types.ObjectId,
ref: "Family",
},
lastName: {
type: String,
required: true,
Expand Down Expand Up @@ -225,6 +235,10 @@ const userSchema = new Schema(
ref: "Organization",
},
],
organizationUserBelongsTo: {
type: Schema.Types.ObjectId,
ref: "Organization",
},
password: {
type: String,
required: true,
Expand Down Expand Up @@ -263,7 +277,6 @@ const userSchema = new Schema(
},
tokenVersion: {
type: Number,
required: true,
default: 0,
},
userType: {
Expand Down
6 changes: 6 additions & 0 deletions src/resolvers/Family/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { FamilyResolvers } from "../../types/generatedGraphQLTypes";
import { users } from "./users";

export const Family: FamilyResolvers = {
users,
};
14 changes: 14 additions & 0 deletions src/resolvers/Family/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { FamilyResolvers } from "../../types/generatedGraphQLTypes";
import { User } from "../../models";
/**
* This resolver function will fetch and return the list of all Members of the Group Chat from database.
* @param parent - An object that is the return value of the resolver for this field's parent.
* @returns An `object` that contains the Member data.
*/
export const users: FamilyResolvers["users"] = async (parent) => {
return await User.find({
_id: {
$in: parent.users,
},
}).lean();
};
86 changes: 86 additions & 0 deletions src/resolvers/Mutation/adminAddFamilyMember.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import "dotenv/config";
import type { MutationResolvers } from "../../types/generatedGraphQLTypes";
import { errors, requestContext } from "../../libraries";
import { superAdminCheck } from "../../utilities";
import { User } from "../../models";
import { Family } from "../../models/Family";
import {
FAMILY_NOT_FOUND_ERROR,
USER_ALREADY_MEMBER_ERROR,
USER_NOT_FOUND_ERROR,
} from "../../constants";
/**
* This function adds user to the family.
* @param _parent - parent of current request
* @param args - payload provided with the request
* @param context - context of the entire application
* @remarks The following checks are done:
* 1. If the family exists
* 2. If the user exists
* 3. If the user is already member of the family
* @returns Updated family
*/
export const addUserToFamily: MutationResolvers["addUserToFamily"] = async (
_parent,
args,
context
) => {
const family = await Family.findOne({
_id: args.familyId,
}).lean();

const currentUser = await User.findById({
_id: context.userId,
});

//check whether user is superadmin
if (currentUser) {
superAdminCheck(currentUser);
}

//check wheather family exists
if (!family) {
throw new errors.NotFoundError(
requestContext.translate(FAMILY_NOT_FOUND_ERROR.MESSAGE),
FAMILY_NOT_FOUND_ERROR.CODE,
FAMILY_NOT_FOUND_ERROR.PARAM
);
}

// Checks whether user with _id === args.userId exists.
if (currentUser === null) {
throw new errors.NotFoundError(
requestContext.translate(USER_NOT_FOUND_ERROR.MESSAGE),
USER_NOT_FOUND_ERROR.CODE,
USER_NOT_FOUND_ERROR.PARAM
);
}

const isUserFamilyMember = family.users.some((user) => {
user.equals(args.userId);
});

// Checks whether user with _id === args.userId is already a member of Family.
if (isUserFamilyMember === true) {
throw new errors.ConflictError(
requestContext.translate(USER_ALREADY_MEMBER_ERROR.MESSAGE),
USER_ALREADY_MEMBER_ERROR.CODE,
USER_ALREADY_MEMBER_ERROR.PARAM
);
}

// Adds args.userId to users lists on family group and return the updated family.
return await Family.findOneAndUpdate(
{
_id: args.familyId,
},
{
$push: {
users: args.userId,
},
},
{
new: true,
}
).lean();
};
Loading