Merge branch 'julius-dev' of Software_Engineering_I/greenvironment-server into master

pull/5/head
Trivernis 5 years ago committed by Gitea
commit 7815fe011a

@ -31,6 +31,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- findUser not being implemented
- style issues
- graphql schema for denyRequest using the wrong parameters
- sendRequest allowing duplicates
### Added
- Added `deleteable' field on post
## [0.9] - 2019-10-29

@ -125,7 +125,7 @@ export function resolver(req: any, res: any): any {
globals.logger.warn(err.message);
globals.logger.debug(err.stack);
res.status(status.BAD_REQUEST);
return err.graphqlError || err.message;
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(status.BAD_REQUEST);
@ -156,11 +156,11 @@ export function resolver(req: any, res: any): any {
value: user.token(),
};
} catch (err) {
res.status(400);
return err.graphqlError;
res.status(status.BAD_REQUEST);
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(400);
res.status(status.BAD_REQUEST);
return new GraphQLError("No email or password specified.");
}
},
@ -178,7 +178,7 @@ export function resolver(req: any, res: any): any {
globals.logger.warn(err.message);
globals.logger.debug(err.stack);
res.status(status.BAD_REQUEST);
return err.graphqlError || err.message;
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(status.BAD_REQUEST);
@ -193,7 +193,7 @@ export function resolver(req: any, res: any): any {
await user.save();
return user.settings;
} catch (err) {
res.status(400);
res.status(status.BAD_REQUEST);
return new GraphQLError("Invalid settings json.");
}
} else {
@ -281,7 +281,7 @@ export function resolver(req: any, res: any): any {
globals.logger.warn(err.message);
globals.logger.debug(err.stack);
res.status(status.BAD_REQUEST);
return err.graphqlError || err.message;
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(status.BAD_REQUEST);
@ -294,7 +294,12 @@ export function resolver(req: any, res: any): any {
return new NotLoggedInGqlError();
}
if (receiver && type) {
return await dataaccess.createRequest(req.session.userId, receiver, type);
try {
return await dataaccess.createRequest(req.session.userId, receiver, type);
} catch (err) {
res.status(status.BAD_REQUEST);
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(status.BAD_REQUEST);
return new GraphQLError("No receiver or type given.");
@ -328,7 +333,7 @@ export function resolver(req: any, res: any): any {
globals.logger.warn(err.message);
globals.logger.debug(err.stack);
res.status(status.BAD_REQUEST);
return err.graphqlError || err.message;
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(status.BAD_REQUEST);
@ -349,7 +354,12 @@ export function resolver(req: any, res: any): any {
},
async createGroup({name, members}: { name: string, members: number[] }) {
if (req.session.userId) {
return await dataaccess.createGroup(name, req.session.userId, members);
try {
return await dataaccess.createGroup(name, req.session.userId, members);
} catch (err) {
res.status(status.BAD_REQUEST);
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
return new NotLoggedInGqlError();
}
@ -361,7 +371,7 @@ export function resolver(req: any, res: any): any {
.changeGroupMembership(id, req.session.userId, dataaccess.MembershipChangeAction.ADD);
} catch (err) {
res.status(status.BAD_REQUEST);
return err.graphqlError;
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(status.UNAUTHORIZED);
@ -375,7 +385,7 @@ export function resolver(req: any, res: any): any {
.changeGroupMembership(id, req.session.userId, dataaccess.MembershipChangeAction.REMOVE);
} catch (err) {
res.status(status.BAD_REQUEST);
return err.graphqlError;
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(status.UNAUTHORIZED);
@ -395,7 +405,7 @@ export function resolver(req: any, res: any): any {
.changeGroupMembership(groupId, userId, dataaccess.MembershipChangeAction.OP);
} catch (err) {
res.status(status.BAD_REQUEST);
return err.graphqlError;
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
@ -420,7 +430,7 @@ export function resolver(req: any, res: any): any {
.changeGroupMembership(groupId, userId, dataaccess.MembershipChangeAction.DEOP);
} catch (err) {
res.status(status.BAD_REQUEST);
return err.graphqlError;
return err.graphqlError ?? new GraphQLError(err.message);
}
} else {
res.status(status.UNAUTHORIZED);

@ -284,6 +284,9 @@ type Post {
"the type of vote the user performed on the post"
userVote(userId: ID!): VoteType
"if the post can be deleted by the specified user"
deleteable(userId: ID!): Boolean
}
"represents a request of any type"

@ -2,7 +2,9 @@ import * as crypto from "crypto";
import * as sqz from "sequelize";
import {Sequelize} from "sequelize-typescript";
import {ChatNotFoundError} from "./errors/ChatNotFoundError";
import {DuplicatedRequestError} from "./errors/DuplicatedRequestError";
import {EmailAlreadyRegisteredError} from "./errors/EmailAlreadyRegisteredError";
import {GroupAlreadyExistsError} from "./errors/GroupAlreadyExistsError";
import {GroupNotFoundError} from "./errors/GroupNotFoundError";
import {InvalidLoginError} from "./errors/InvalidLoginError";
import {NoActionSpecifiedError} from "./errors/NoActionSpecifiedError";
@ -231,9 +233,16 @@ namespace dataaccess {
export async function createRequest(sender: number, receiver: number, requestType?: RequestType) {
requestType = requestType || RequestType.FRIENDREQUEST;
const request = await models.Request.create({senderId: sender, receiverId: receiver, requestType});
globals.internalEmitter.emit(InternalEvents.REQUESTCREATE, request);
return request;
const requestExists = !!await models.Request.findOne({where:
{senderId: sender, receiverId: receiver, requestType}});
if (!requestExists) {
const request = await models.Request.create({senderId: sender, receiverId: receiver, requestType});
globals.internalEmitter.emit(InternalEvents.REQUESTCREATE, request);
return request;
} else {
throw new DuplicatedRequestError();
}
}
/**
@ -243,19 +252,25 @@ namespace dataaccess {
* @param members
*/
export async function createGroup(name: string, creator: number, members: number[]): Promise<models.Group> {
members = members || [];
return sequelize.transaction(async (t) => {
members.push(creator);
const groupChat = await createChat(...members);
const group = await models.Group.create({name, creatorId: creator, chatId: groupChat.id}, {transaction: t});
const creatorUser = await models.User.findByPk(creator, {transaction: t});
await group.$add("rAdmins", creatorUser, {transaction: t});
for (const member of members) {
const user = await models.User.findByPk(member, {transaction: t});
await group.$add("rMembers", user, {transaction: t});
}
return group;
});
const groupNameExists = !!await models.Group.findOne({where: {name}});
if (!groupNameExists) {
members = members || [];
return sequelize.transaction(async (t) => {
members.push(creator);
const groupChat = await createChat(...members);
const group = await models.Group
.create({name, creatorId: creator, chatId: groupChat.id}, {transaction: t});
const creatorUser = await models.User.findByPk(creator, {transaction: t});
await group.$add("rAdmins", creatorUser, {transaction: t});
for (const member of members) {
const user = await models.User.findByPk(member, {transaction: t});
await group.$add("rMembers", user, {transaction: t});
}
return group;
});
} else {
throw new GroupAlreadyExistsError(name);
}
}
/**

@ -0,0 +1,7 @@
import {BaseError} from "./BaseError";
export class DuplicatedRequestError extends BaseError {
constructor() {
super(`Request already exists.`);
}
}

@ -0,0 +1,7 @@
import {BaseError} from "./BaseError";
export class GroupAlreadyExistsError extends BaseError {
constructor(name: string) {
super(`A group with the name "${name}" already exists.`);
}
}

@ -1,4 +1,14 @@
import {BelongsTo, BelongsToMany, Column, ForeignKey, HasMany, Model, NotNull, Table} from "sequelize-typescript";
import {
BelongsTo,
BelongsToMany,
Column,
ForeignKey,
HasMany,
Model,
NotNull,
Table,
Unique,
} from "sequelize-typescript";
import {ChatRoom} from "./ChatRoom";
import {Event} from "./Event";
import {GroupAdmin} from "./GroupAdmin";
@ -8,7 +18,8 @@ import {User} from "./User";
@Table({underscored: true})
export class Group extends Model<Group> {
@NotNull
@Column({allowNull: false})
@Unique
@Column({allowNull: false, unique: true})
public name: string;
@NotNull

@ -96,4 +96,12 @@ export class Post extends Model<Post> {
const votes = await this.$get("rVotes", {where: {id: userId}}) as Array<User & {PostVote: PostVote}>;
return votes[0]?.PostVote?.voteType;
}
/**
* Returns if the post can be deleted by the user with the given id.
* @param userId
*/
public async deleteable({userId}: {userId: number}): Promise<boolean> {
return Number(userId) === Number(this.authorId);
}
}

@ -35,10 +35,23 @@ export class Request extends Model<Request> {
@BelongsTo(() => User, "receiverId")
public rReceiver: User;
/**
* Wrapper to return the request type for the request
*/
public get type(): RequestType {
return this.requestType;
}
/**
* The receiver of the request
*/
public async receiver(): Promise<User> {
return await this.$get("rReceiver") as User;
}
/**
* The sender of the request.
*/
public async sender(): Promise<User> {
return await this.$get("rSender") as User;
}

Loading…
Cancel
Save