Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions src/dao/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { UserPhoneModel } from "../model/user/Phone";
import { UserSensitiveModel } from "../model/user/Sensitive";
import { UserEmailModel } from "../model/user/Email";
import { UserPmiModel } from "../model/user/Pmi";
import { UserAgreementModel } from "../model/user/Agreement";

export const UserDAO = DAOImplement(UserModel) as ReturnType<DAO<UserModel>>;

Expand All @@ -42,6 +43,8 @@ export const UserSensitiveDAO = DAOImplement(UserSensitiveModel) as ReturnType<

export const UserPmiDAO = DAOImplement(UserPmiModel) as ReturnType<DAO<UserPmiModel>>;

export const UserAgreementDAO = DAOImplement(UserAgreementModel) as ReturnType<DAO<UserAgreementModel>>;

export const RoomDAO = DAOImplement(RoomModel) as ReturnType<DAO<RoomModel>>;

export const RoomUserDAO = DAOImplement(RoomUserModel) as ReturnType<DAO<RoomUserModel>>;
Expand Down
2 changes: 2 additions & 0 deletions src/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { OAuthUsersModel } from "./oauth/oauth-users";
import { UserSensitiveModel } from "./user/Sensitive";
import { UserEmailModel } from "./user/Email";
import { UserPmiModel } from "./user/Pmi";
import { UserAgreementModel } from "./user/Agreement";
import { PartnerModel } from "./partner/Partner";
import { PartnerRoomModel } from "./partner/PartnerRoom";

Expand All @@ -34,6 +35,7 @@ export type Model =
| UserEmailModel
| UserSensitiveModel
| UserPmiModel
| UserAgreementModel
| RoomModel
| RoomUserModel
| RoomPeriodicConfigModel
Expand Down
26 changes: 26 additions & 0 deletions src/model/user/Agreement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Column, Entity, Index } from "typeorm";
import { Content } from "../Content";

@Entity({
name: "user_agreement",
})
export class UserAgreementModel extends Content {
@Index("user_agreement_user_uuid_uindex", {
unique: true,
})
@Column({
length: 40,
})
user_uuid: string;

@Column({
default: false,
})
is_agree_collect_data: boolean;

@Index("user_agreement_is_delete_index")
@Column({
default: false,
})
is_delete: boolean;
}
2 changes: 2 additions & 0 deletions src/thirdPartyService/TypeORMService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { OAuthSecretsModel } from "../model/oauth/oauth-secrets";
import { OAuthUsersModel } from "../model/oauth/oauth-users";
import { UserEmailModel } from "../model/user/Email";
import { UserPmiModel } from "../model/user/Pmi";
import { UserAgreementModel } from "../model/user/Agreement";
import { PartnerModel } from "../model/partner/Partner";
import { PartnerRoomModel } from "../model/partner/PartnerRoom";

Expand All @@ -44,6 +45,7 @@ export const dataSource = new DataSource({
UserEmailModel,
UserSensitiveModel,
UserPmiModel,
UserAgreementModel,
RoomModel,
RoomUserModel,
RoomPeriodicConfigModel,
Expand Down
6 changes: 6 additions & 0 deletions src/v1/controller/user/Router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import { BindingGithub } from "./binding/platform/github/Binding";
import { BindingGoogle } from "./binding/platform/google/Binding";
import { BindingEmail } from "./binding/platform/email/Binding";
import { BindingApple } from "./binding/platform/apple/Binding";
import { AgreementSet } from "./agreement/Set";
import { AgreementGet } from "./agreement/Get";
import { AgreementGetToRtc } from "./agreement/GetToRtc";

export const userRouters: Readonly<Array<ControllerClass<any, any>>> = Object.freeze([
Rename,
Expand All @@ -38,4 +41,7 @@ export const userRouters: Readonly<Array<ControllerClass<any, any>>> = Object.fr
DeleteAccount,
UploadAvatarStart,
UploadAvatarFinish,
AgreementSet,
AgreementGet,
AgreementGetToRtc
]);
47 changes: 47 additions & 0 deletions src/v1/controller/user/agreement/Get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { AbstractController, ControllerClassParams } from "../../../../abstract/controller";
import { Status } from "../../../../constants/Project";
import { Controller } from "../../../../decorator/Controller";
import { FastifySchema, Response, ResponseError } from "../../../../types/Server";

import { ServiceUserAgreement } from "../../../service/user/UserAgreement";

@Controller<RequestType, ResponseType>({
method: "post",
path: "user/agreement/get",
auth: true,
})
export class AgreementGet extends AbstractController<RequestType, ResponseType> {
public static readonly schema: FastifySchema<RequestType> = {};

public readonly svc: {
userAgreement: ServiceUserAgreement;
};

public constructor(params: ControllerClassParams) {
super(params);

this.svc = {
userAgreement: new ServiceUserAgreement(this.userUUID),
};
}

public async execute(): Promise<Response<ResponseType>> {
const isAgree = await this.svc.userAgreement.isAgreeCollectData();
return {
status: Status.Success,
data: {
isAgree
}
}
}

public errorHandler(error: Error): ResponseError {
return this.autoHandlerError(error);
}
}

interface RequestType {}

interface ResponseType {
isAgree: boolean;
}
108 changes: 108 additions & 0 deletions src/v1/controller/user/agreement/GetToRtc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { AbstractController, ControllerClassParams } from "../../../../abstract/controller";
import { Status } from "../../../../constants/Project";
import { Controller } from "../../../../decorator/Controller";
import { FastifySchema, Response, ResponseError } from "../../../../types/Server";

import { ServiceUserAgreement } from "../../../service/user/UserAgreement";
import { RoomUserModel } from "../../../../model/room/RoomUser";
import { dataSource } from "../../../../thirdPartyService/TypeORMService";
import { UserAgreementModel } from "./../../../../model/user/Agreement";

@Controller<RequestType, ResponseType>({
method: "get",
path: "private-polic/get",
auth: false,
skipAutoHandle: false,
enable: true
})
export class AgreementGetToRtc extends AbstractController<RequestType, ResponseType> {
public static readonly schema: FastifySchema<RequestType> = {
querystring: {
type: "object",
required: ["uid"],
properties: {
uid: {
type: "string"
},
room_uuid: {
type: "string"
}
},
},
};

public readonly svc: {
userAgreement: ServiceUserAgreement;
};

public constructor(params: ControllerClassParams) {
super(params);

this.svc = {
userAgreement: new ServiceUserAgreement(this.userUUID),
};
}

public async execute(): Promise<Response<ResponseType>> {
const rtcUidstr = this.querystring.uid;
const room_uuid = this.querystring.room_uuid;
const rtcUids = rtcUidstr.split(",");
const userAgreementMap:Map<string, boolean> = new Map(rtcUids.map(rtc_uid => [rtc_uid, false]));
const length = rtcUids.length;
if (length > 0) {
let i = 0;
while (i < length) {
const j = i + 50;
const batchedRtcUids = rtcUids.slice(i, j);
const roomUserInfos = await this.getRoomUserInfos(room_uuid, batchedRtcUids);
const userUuids = roomUserInfos.map(user => user.user_uuid);
if (userUuids.length > 0) {
const userAgreements = await this.getUserAgreements(userUuids);
for (const userInfo of roomUserInfos) {
const { rtc_uid, user_uuid } = userInfo;
const userAgreement = userAgreements.find(ua => ua.user_uuid === user_uuid);
if (userAgreement) {
userAgreementMap.set(rtc_uid, userAgreement.is_agree_collect_data);
} else {
userAgreementMap.set(rtc_uid, true);
}
}
}
i = j;
}
}
return {
status: Status.Success,
data: Object.fromEntries(userAgreementMap)
}
}

private async getRoomUserInfos(room_uuid: string, rtc_uids: string[]): Promise<RoomUserModel[]> {
return dataSource
.createQueryBuilder(RoomUserModel, "ru")
.where("ru.room_uuid = :room_uuid", { room_uuid })
.andWhere("ru.rtc_uid IN (:...rtc_uids)", { rtc_uids })
.getMany();
}
private async getUserAgreements(userUuids: string[]): Promise<UserAgreementModel[]> {
return dataSource
.createQueryBuilder(UserAgreementModel, "ua")
.where("ua.user_uuid IN (:...userUuids)", { userUuids })
.getMany();
}

public errorHandler(error: Error): ResponseError {
return this.autoHandlerError(error);
}
}

interface RequestType {
querystring: {
uid: string;
room_uuid: string;
};
}

interface ResponseType {
[key: string]: boolean;
}
61 changes: 61 additions & 0 deletions src/v1/controller/user/agreement/Set.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { AbstractController, ControllerClassParams } from "../../../../abstract/controller";
import { Status } from "../../../../constants/Project";
import { Controller } from "../../../../decorator/Controller";
import { FastifySchema, Response, ResponseError } from "../../../../types/Server";

import { ServiceUserAgreement } from "../../../service/user/UserAgreement";

@Controller<RequestType, ResponseType>({
method: "post",
path: "user/agreement/set",
auth: true,
})
export class AgreementSet extends AbstractController<RequestType, ResponseType> {
public static readonly schema: FastifySchema<RequestType> = {
body: {
type: "object",
required: ["isAgree"],
properties: {
isAgree: {
type: "boolean"
},
},
},
};

public readonly svc: {
userAgreement: ServiceUserAgreement;
};

public constructor(params: ControllerClassParams) {
super(params);

this.svc = {
userAgreement: new ServiceUserAgreement(this.userUUID),
};
}

public async execute(): Promise<Response<ResponseType>> {
await this.svc.userAgreement.set(this.body.isAgree);
return {
status: Status.Success,
data: {
userUUID: this.userUUID
}
};
}

public errorHandler(error: Error): ResponseError {
return this.autoHandlerError(error);
}
}

interface RequestType {
body: {
isAgree: boolean;
};
}

interface ResponseType {
userUUID: string;
}
65 changes: 65 additions & 0 deletions src/v1/service/user/UserAgreement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { UserAgreementDAO } from "../../../dao";
import { DeleteResult, EntityManager, InsertResult } from "typeorm";
import { UpdateResult } from "typeorm/query-builder/result/UpdateResult";

export class ServiceUserAgreement {
constructor(private readonly userUUID: string) {}
public async isAgreeCollectData(): Promise<boolean> {
const bol = await ServiceUserAgreement.hasCollectData(this.userUUID);
if (bol) {
const isAgree = await ServiceUserAgreement.isAgreeCollectData(this.userUUID);
return isAgree;
}
return true;
}
public async hasCollectData(): Promise<boolean> {
return await ServiceUserAgreement.hasCollectData(this.userUUID);
}
public static async isAgreeCollectData(userUUID: string): Promise<boolean> {
const result = await UserAgreementDAO().findOne(["is_agree_collect_data"], {
user_uuid: userUUID,
});
return Boolean(result && result.is_agree_collect_data);
}
public static async hasCollectData(userUUID: string): Promise<boolean> {
const result = await UserAgreementDAO().findOne(["user_uuid"], {
user_uuid: userUUID,
});
return Boolean(result);
}
public async set(
is_agree_collect_data: boolean,
t?: EntityManager,
): Promise<InsertResult|UpdateResult> {
const has = await this.hasCollectData();
if (!has) {
return await this.create(is_agree_collect_data, t);
}
return await this.update(is_agree_collect_data, t);
}
public async create(
is_agree_collect_data: boolean,
t?: EntityManager,
): Promise<InsertResult> {
return await UserAgreementDAO(t).insert({
user_uuid: this.userUUID,
is_agree_collect_data,
});
}
public async update(is_agree_collect_data: boolean, t?: EntityManager): Promise<UpdateResult> {
return await UserAgreementDAO(t).update(
{
is_agree_collect_data,
},
{
user_uuid: this.userUUID,
},
);
}

public async physicalDeletion(t?: EntityManager): Promise<DeleteResult> {
return await UserAgreementDAO(t).physicalDeletion({
user_uuid: this.userUUID,
});
}
}
Loading