@goweekdays/core 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +254 -10
- package/dist/index.js +1919 -432
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1791 -301
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -11324,12 +11324,20 @@ var require_follow_redirects = __commonJS({
|
|
|
11324
11324
|
});
|
|
11325
11325
|
|
|
11326
11326
|
// src/models/verification.model.ts
|
|
11327
|
+
import { BadRequestError } from "@goweekdays/utils";
|
|
11327
11328
|
import { ObjectId } from "mongodb";
|
|
11328
11329
|
var MVerification = class {
|
|
11329
11330
|
constructor(value) {
|
|
11330
11331
|
this._id = value._id ?? new ObjectId();
|
|
11331
11332
|
this.type = value.type ?? "";
|
|
11332
11333
|
this.email = value.email ?? "";
|
|
11334
|
+
if (this.metadata?.org) {
|
|
11335
|
+
try {
|
|
11336
|
+
this.metadata.org = new ObjectId(this.metadata?.org);
|
|
11337
|
+
} catch (error) {
|
|
11338
|
+
throw new BadRequestError("Invalid org ID.");
|
|
11339
|
+
}
|
|
11340
|
+
}
|
|
11333
11341
|
this.metadata = value.metadata ?? {};
|
|
11334
11342
|
this.status = value.status ?? "pending";
|
|
11335
11343
|
this.createdAt = value.createdAt ?? /* @__PURE__ */ new Date();
|
|
@@ -11340,7 +11348,7 @@ var MVerification = class {
|
|
|
11340
11348
|
|
|
11341
11349
|
// src/repositories/verification.repository.ts
|
|
11342
11350
|
import {
|
|
11343
|
-
BadRequestError,
|
|
11351
|
+
BadRequestError as BadRequestError2,
|
|
11344
11352
|
InternalServerError,
|
|
11345
11353
|
logger,
|
|
11346
11354
|
paginate,
|
|
@@ -11353,6 +11361,18 @@ function useVerificationRepo() {
|
|
|
11353
11361
|
throw new InternalServerError("Unable to connect to server.");
|
|
11354
11362
|
}
|
|
11355
11363
|
const collection = db.collection("verifications");
|
|
11364
|
+
async function createIndex() {
|
|
11365
|
+
try {
|
|
11366
|
+
await collection.createIndex([
|
|
11367
|
+
{ email: 1 },
|
|
11368
|
+
{ type: 1 },
|
|
11369
|
+
{ status: 1 },
|
|
11370
|
+
{ "metadata.org": 1 }
|
|
11371
|
+
]);
|
|
11372
|
+
} catch (error) {
|
|
11373
|
+
throw new InternalServerError("Failed to create index.");
|
|
11374
|
+
}
|
|
11375
|
+
}
|
|
11356
11376
|
async function createTextIndex() {
|
|
11357
11377
|
try {
|
|
11358
11378
|
await collection.createIndex({
|
|
@@ -11379,7 +11399,7 @@ function useVerificationRepo() {
|
|
|
11379
11399
|
try {
|
|
11380
11400
|
_id = new ObjectId2(_id);
|
|
11381
11401
|
} catch (error) {
|
|
11382
|
-
throw new
|
|
11402
|
+
throw new BadRequestError2("Invalid ID.");
|
|
11383
11403
|
}
|
|
11384
11404
|
try {
|
|
11385
11405
|
return await collection.findOne({ _id });
|
|
@@ -11395,7 +11415,8 @@ function useVerificationRepo() {
|
|
|
11395
11415
|
limit = 10,
|
|
11396
11416
|
sort = {},
|
|
11397
11417
|
status = "active",
|
|
11398
|
-
type = ""
|
|
11418
|
+
type = "",
|
|
11419
|
+
email = ""
|
|
11399
11420
|
} = {}) {
|
|
11400
11421
|
page = page > 0 ? page - 1 : 0;
|
|
11401
11422
|
const query = { status };
|
|
@@ -11406,6 +11427,9 @@ function useVerificationRepo() {
|
|
|
11406
11427
|
if (type) {
|
|
11407
11428
|
query.type = type;
|
|
11408
11429
|
}
|
|
11430
|
+
if (email) {
|
|
11431
|
+
query.email = email;
|
|
11432
|
+
}
|
|
11409
11433
|
try {
|
|
11410
11434
|
const items = await collection.aggregate([
|
|
11411
11435
|
{ $match: query },
|
|
@@ -11441,7 +11465,7 @@ function useVerificationRepo() {
|
|
|
11441
11465
|
try {
|
|
11442
11466
|
_id = new ObjectId2(_id);
|
|
11443
11467
|
} catch (error) {
|
|
11444
|
-
throw new
|
|
11468
|
+
throw new BadRequestError2("Invalid ID.");
|
|
11445
11469
|
}
|
|
11446
11470
|
try {
|
|
11447
11471
|
return await collection.updateOne(
|
|
@@ -11454,6 +11478,7 @@ function useVerificationRepo() {
|
|
|
11454
11478
|
}
|
|
11455
11479
|
}
|
|
11456
11480
|
return {
|
|
11481
|
+
createIndex,
|
|
11457
11482
|
createTextIndex,
|
|
11458
11483
|
add,
|
|
11459
11484
|
getVerifications,
|
|
@@ -11469,7 +11494,7 @@ import {
|
|
|
11469
11494
|
compileHandlebar,
|
|
11470
11495
|
logger as logger3,
|
|
11471
11496
|
getDirectory,
|
|
11472
|
-
BadRequestError as
|
|
11497
|
+
BadRequestError as BadRequestError5,
|
|
11473
11498
|
NotFoundError,
|
|
11474
11499
|
InternalServerError as InternalServerError3,
|
|
11475
11500
|
useAtlas as useAtlas3
|
|
@@ -11513,13 +11538,15 @@ var SPACES_BUCKET = process.env.SPACES_BUCKET;
|
|
|
11513
11538
|
var PAYPAL_CLIENT_ID = process.env.PAYPAL_CLIENT_ID ?? "";
|
|
11514
11539
|
var PAYPAL_CLIENT_SECRET = process.env.PAYPAL_CLIENT_SECRET ?? "";
|
|
11515
11540
|
var PAYPAL_API_URL = process.env.PAYPAL_API_URL ?? "https://api-m.sandbox.paypal.com";
|
|
11541
|
+
var XENDIT_SECRET_KEY = process.env.XENDIT_SECRET_KEY ?? "";
|
|
11542
|
+
var XENDIT_BASE_URL = process.env.XENDIT_BASE_URL ?? "https://api.xendit.co";
|
|
11516
11543
|
|
|
11517
11544
|
// src/repositories/user.repository.ts
|
|
11518
11545
|
import { ObjectId as ObjectId4 } from "mongodb";
|
|
11519
11546
|
|
|
11520
11547
|
// src/models/user.model.ts
|
|
11521
11548
|
import { ObjectId as ObjectId3 } from "mongodb";
|
|
11522
|
-
import { BadRequestError as
|
|
11549
|
+
import { BadRequestError as BadRequestError3 } from "@goweekdays/utils";
|
|
11523
11550
|
var MUserRole = class {
|
|
11524
11551
|
constructor(value) {
|
|
11525
11552
|
this.name = value.name ?? "";
|
|
@@ -11548,13 +11575,13 @@ var MUser = class {
|
|
|
11548
11575
|
try {
|
|
11549
11576
|
role.role = new ObjectId3(role.role);
|
|
11550
11577
|
} catch (error) {
|
|
11551
|
-
throw new
|
|
11578
|
+
throw new BadRequestError3("Invalid role ID.");
|
|
11552
11579
|
}
|
|
11553
11580
|
if (!role.app) {
|
|
11554
|
-
throw new
|
|
11581
|
+
throw new BadRequestError3("App is required.");
|
|
11555
11582
|
}
|
|
11556
11583
|
if (!role.name) {
|
|
11557
|
-
throw new
|
|
11584
|
+
throw new BadRequestError3("Name is required.");
|
|
11558
11585
|
}
|
|
11559
11586
|
role.status = role.status ?? "active";
|
|
11560
11587
|
});
|
|
@@ -11574,7 +11601,7 @@ import {
|
|
|
11574
11601
|
useAtlas as useAtlas2,
|
|
11575
11602
|
InternalServerError as InternalServerError2,
|
|
11576
11603
|
logger as logger2,
|
|
11577
|
-
BadRequestError as
|
|
11604
|
+
BadRequestError as BadRequestError4,
|
|
11578
11605
|
paginate as paginate2
|
|
11579
11606
|
} from "@goweekdays/utils";
|
|
11580
11607
|
function useUserRepo() {
|
|
@@ -11614,7 +11641,7 @@ function useUserRepo() {
|
|
|
11614
11641
|
logger2.log({ level: "error", message: `${error}` });
|
|
11615
11642
|
const isDuplicated = error.message.includes("duplicate");
|
|
11616
11643
|
if (isDuplicated) {
|
|
11617
|
-
throw new
|
|
11644
|
+
throw new BadRequestError4("Item name already exists");
|
|
11618
11645
|
}
|
|
11619
11646
|
throw new InternalServerError2("Internal server error.");
|
|
11620
11647
|
}
|
|
@@ -11745,14 +11772,14 @@ function useUserRepo() {
|
|
|
11745
11772
|
async function updateUserFieldById({ _id, field, value } = {}, session) {
|
|
11746
11773
|
const allowedFields = ["gender", "email", "contact", "profile"];
|
|
11747
11774
|
if (!allowedFields.includes(field)) {
|
|
11748
|
-
throw new
|
|
11775
|
+
throw new BadRequestError4(
|
|
11749
11776
|
`Field "${field}" is not allowed to be updated.`
|
|
11750
11777
|
);
|
|
11751
11778
|
}
|
|
11752
11779
|
try {
|
|
11753
11780
|
_id = new ObjectId4(_id);
|
|
11754
11781
|
} catch (error) {
|
|
11755
|
-
throw new
|
|
11782
|
+
throw new BadRequestError4("Invalid ID.");
|
|
11756
11783
|
}
|
|
11757
11784
|
try {
|
|
11758
11785
|
await collection.updateOne(
|
|
@@ -11770,7 +11797,7 @@ function useUserRepo() {
|
|
|
11770
11797
|
try {
|
|
11771
11798
|
_id = new ObjectId4(_id);
|
|
11772
11799
|
} catch (error) {
|
|
11773
|
-
throw new
|
|
11800
|
+
throw new BadRequestError4("Invalid user ID.");
|
|
11774
11801
|
}
|
|
11775
11802
|
role = new MUserRole(role);
|
|
11776
11803
|
try {
|
|
@@ -11835,7 +11862,7 @@ function useVerificationService() {
|
|
|
11835
11862
|
try {
|
|
11836
11863
|
const user = await getByEmailApp(email, metadata.app);
|
|
11837
11864
|
if (user) {
|
|
11838
|
-
throw new
|
|
11865
|
+
throw new BadRequestError5(
|
|
11839
11866
|
`User already a user in ${metadata.app} app.`
|
|
11840
11867
|
);
|
|
11841
11868
|
}
|
|
@@ -11916,41 +11943,49 @@ function useVerificationService() {
|
|
|
11916
11943
|
page = 1,
|
|
11917
11944
|
status = "",
|
|
11918
11945
|
type = "",
|
|
11946
|
+
email = "",
|
|
11919
11947
|
limit = 10
|
|
11920
11948
|
} = {}) {
|
|
11921
11949
|
try {
|
|
11922
|
-
return await _getVerifications({
|
|
11950
|
+
return await _getVerifications({
|
|
11951
|
+
search,
|
|
11952
|
+
page,
|
|
11953
|
+
status,
|
|
11954
|
+
type,
|
|
11955
|
+
limit,
|
|
11956
|
+
email
|
|
11957
|
+
});
|
|
11923
11958
|
} catch (error) {
|
|
11924
11959
|
throw error;
|
|
11925
11960
|
}
|
|
11926
11961
|
}
|
|
11927
11962
|
function errorByType(type, status) {
|
|
11928
11963
|
if (type === "user-invite" && status === "expired") {
|
|
11929
|
-
throw new
|
|
11964
|
+
throw new BadRequestError5(
|
|
11930
11965
|
"Invitation has already expired, please contact admin to resend the invitation."
|
|
11931
11966
|
);
|
|
11932
11967
|
}
|
|
11933
11968
|
if (type === "user-sign-up" && status === "expired") {
|
|
11934
|
-
throw new
|
|
11969
|
+
throw new BadRequestError5(
|
|
11935
11970
|
"Sign up verification has expired, please sign up again to get a new verification link."
|
|
11936
11971
|
);
|
|
11937
11972
|
}
|
|
11938
11973
|
if (type === "user-invite" && status === "complete") {
|
|
11939
|
-
throw new
|
|
11974
|
+
throw new BadRequestError5(
|
|
11940
11975
|
"User already registered, please login to continue."
|
|
11941
11976
|
);
|
|
11942
11977
|
}
|
|
11943
11978
|
if (type === "forget-password" && status === "complete") {
|
|
11944
|
-
throw new
|
|
11979
|
+
throw new BadRequestError5(
|
|
11945
11980
|
"Forget password verification has already been used, please request a new one."
|
|
11946
11981
|
);
|
|
11947
11982
|
}
|
|
11948
11983
|
if (type === "forget-password" && status === "expired") {
|
|
11949
|
-
throw new
|
|
11984
|
+
throw new BadRequestError5(
|
|
11950
11985
|
"Forget password verification has expired, please request a new one."
|
|
11951
11986
|
);
|
|
11952
11987
|
}
|
|
11953
|
-
throw new
|
|
11988
|
+
throw new BadRequestError5("Invalid verification.");
|
|
11954
11989
|
}
|
|
11955
11990
|
async function verify(id) {
|
|
11956
11991
|
const session = useAtlas3.getClient()?.startSession();
|
|
@@ -11964,7 +11999,7 @@ function useVerificationService() {
|
|
|
11964
11999
|
errorByType(_id.type, "expired");
|
|
11965
12000
|
}
|
|
11966
12001
|
if (_id.status === "complete") {
|
|
11967
|
-
throw new
|
|
12002
|
+
throw new BadRequestError5("Verification already completed.");
|
|
11968
12003
|
}
|
|
11969
12004
|
const expiration = new Date(_id.expireAt).getTime();
|
|
11970
12005
|
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
@@ -11992,7 +12027,7 @@ function useVerificationService() {
|
|
|
11992
12027
|
}
|
|
11993
12028
|
if (appMember?.length && _id.type === "user-invite") {
|
|
11994
12029
|
await _updateStatusById(id, "expired");
|
|
11995
|
-
throw new
|
|
12030
|
+
throw new BadRequestError5(
|
|
11996
12031
|
`Invalid user invitation. User is already a user in the ${_id.metadata?.app} app.`
|
|
11997
12032
|
);
|
|
11998
12033
|
}
|
|
@@ -12033,12 +12068,12 @@ function useVerificationService() {
|
|
|
12033
12068
|
if (metadata && metadata.referralCode && typeof metadata.referralCode === "string") {
|
|
12034
12069
|
const code = await getUserByReferralCode(metadata.referralCode);
|
|
12035
12070
|
if (!code) {
|
|
12036
|
-
throw new
|
|
12071
|
+
throw new BadRequestError5("Invalid referral code.");
|
|
12037
12072
|
}
|
|
12038
12073
|
}
|
|
12039
12074
|
const user = await getUserByEmail(email);
|
|
12040
12075
|
if (user) {
|
|
12041
|
-
throw new
|
|
12076
|
+
throw new BadRequestError5(
|
|
12042
12077
|
`Email ${email} is already registered, please login to continue.`
|
|
12043
12078
|
);
|
|
12044
12079
|
}
|
|
@@ -12091,7 +12126,7 @@ function useVerificationService() {
|
|
|
12091
12126
|
// src/controllers/verification.controller.ts
|
|
12092
12127
|
import {
|
|
12093
12128
|
AppError,
|
|
12094
|
-
BadRequestError as
|
|
12129
|
+
BadRequestError as BadRequestError6,
|
|
12095
12130
|
InternalServerError as InternalServerError4
|
|
12096
12131
|
} from "@goweekdays/utils";
|
|
12097
12132
|
import Joi from "joi";
|
|
@@ -12121,7 +12156,7 @@ function useVerificationController() {
|
|
|
12121
12156
|
name
|
|
12122
12157
|
});
|
|
12123
12158
|
if (error) {
|
|
12124
|
-
next(new
|
|
12159
|
+
next(new BadRequestError6(error.message));
|
|
12125
12160
|
return;
|
|
12126
12161
|
}
|
|
12127
12162
|
try {
|
|
@@ -12145,7 +12180,7 @@ function useVerificationController() {
|
|
|
12145
12180
|
const validation = Joi.string().email().required();
|
|
12146
12181
|
const { error } = validation.validate(email);
|
|
12147
12182
|
if (error) {
|
|
12148
|
-
next(new
|
|
12183
|
+
next(new BadRequestError6(error.message));
|
|
12149
12184
|
return;
|
|
12150
12185
|
}
|
|
12151
12186
|
try {
|
|
@@ -12166,18 +12201,34 @@ function useVerificationController() {
|
|
|
12166
12201
|
const status = req.query.status ?? "";
|
|
12167
12202
|
const search = req.query.search ?? "";
|
|
12168
12203
|
const page = Number(req.query.page) ?? 1;
|
|
12204
|
+
const type = req.query.type ?? "";
|
|
12205
|
+
const email = req.query.email ?? "";
|
|
12169
12206
|
const validation = Joi.object({
|
|
12170
12207
|
status: Joi.string().required(),
|
|
12171
12208
|
search: Joi.string().optional().allow("", null),
|
|
12172
|
-
page: Joi.number().required()
|
|
12209
|
+
page: Joi.number().required(),
|
|
12210
|
+
type: Joi.string().optional().allow("", null),
|
|
12211
|
+
email: Joi.string().optional().allow("", null)
|
|
12212
|
+
});
|
|
12213
|
+
const { error } = validation.validate({
|
|
12214
|
+
status,
|
|
12215
|
+
search,
|
|
12216
|
+
page,
|
|
12217
|
+
type,
|
|
12218
|
+
email
|
|
12173
12219
|
});
|
|
12174
|
-
const { error } = validation.validate({ status, search, page });
|
|
12175
12220
|
if (error) {
|
|
12176
|
-
next(new
|
|
12221
|
+
next(new BadRequestError6(error.message));
|
|
12177
12222
|
return;
|
|
12178
12223
|
}
|
|
12179
12224
|
try {
|
|
12180
|
-
const items = await _getVerifications({
|
|
12225
|
+
const items = await _getVerifications({
|
|
12226
|
+
status,
|
|
12227
|
+
search,
|
|
12228
|
+
page,
|
|
12229
|
+
type,
|
|
12230
|
+
email
|
|
12231
|
+
});
|
|
12181
12232
|
res.json(items);
|
|
12182
12233
|
return;
|
|
12183
12234
|
} catch (error2) {
|
|
@@ -12189,7 +12240,7 @@ function useVerificationController() {
|
|
|
12189
12240
|
const validation = Joi.string().hex().required();
|
|
12190
12241
|
const { error } = validation.validate(id);
|
|
12191
12242
|
if (error) {
|
|
12192
|
-
next(new
|
|
12243
|
+
next(new BadRequestError6(error.message));
|
|
12193
12244
|
return;
|
|
12194
12245
|
}
|
|
12195
12246
|
try {
|
|
@@ -12205,7 +12256,7 @@ function useVerificationController() {
|
|
|
12205
12256
|
const validation = Joi.string().hex().required();
|
|
12206
12257
|
const { error } = validation.validate(otpId);
|
|
12207
12258
|
if (error) {
|
|
12208
|
-
next(new
|
|
12259
|
+
next(new BadRequestError6(error.message));
|
|
12209
12260
|
return;
|
|
12210
12261
|
}
|
|
12211
12262
|
try {
|
|
@@ -12281,7 +12332,7 @@ function useTokenRepo() {
|
|
|
12281
12332
|
|
|
12282
12333
|
// src/services/user.service.ts
|
|
12283
12334
|
import {
|
|
12284
|
-
BadRequestError as
|
|
12335
|
+
BadRequestError as BadRequestError8,
|
|
12285
12336
|
InternalServerError as InternalServerError7,
|
|
12286
12337
|
NotFoundError as NotFoundError2,
|
|
12287
12338
|
hashPassword,
|
|
@@ -12291,7 +12342,7 @@ import {
|
|
|
12291
12342
|
|
|
12292
12343
|
// src/repositories/file.repository.ts
|
|
12293
12344
|
import {
|
|
12294
|
-
BadRequestError as
|
|
12345
|
+
BadRequestError as BadRequestError7,
|
|
12295
12346
|
InternalServerError as InternalServerError6,
|
|
12296
12347
|
useAtlas as useAtlas5
|
|
12297
12348
|
} from "@goweekdays/utils";
|
|
@@ -12328,7 +12379,7 @@ function useFileRepo() {
|
|
|
12328
12379
|
try {
|
|
12329
12380
|
_id = new ObjectId7(_id);
|
|
12330
12381
|
} catch (error) {
|
|
12331
|
-
throw new
|
|
12382
|
+
throw new BadRequestError7("Invalid file id.");
|
|
12332
12383
|
}
|
|
12333
12384
|
try {
|
|
12334
12385
|
await collection.deleteOne({ _id }, { session });
|
|
@@ -12389,7 +12440,7 @@ function useUserService() {
|
|
|
12389
12440
|
try {
|
|
12390
12441
|
const _user = await getUserByEmail(value.email);
|
|
12391
12442
|
if (_user) {
|
|
12392
|
-
throw new
|
|
12443
|
+
throw new BadRequestError8(`User already exists: ${value.email}.`);
|
|
12393
12444
|
}
|
|
12394
12445
|
const hashedPassword = await hashPassword(value.password);
|
|
12395
12446
|
const user = {
|
|
@@ -12427,19 +12478,19 @@ function useUserService() {
|
|
|
12427
12478
|
try {
|
|
12428
12479
|
const invitation = await _getVerificationById(id);
|
|
12429
12480
|
if (!invitation || !invitation.metadata?.app || !invitation.metadata?.role) {
|
|
12430
|
-
throw new
|
|
12481
|
+
throw new BadRequestError8("Invalid invitation.");
|
|
12431
12482
|
}
|
|
12432
12483
|
if (invitation.status === "complete") {
|
|
12433
|
-
throw new
|
|
12484
|
+
throw new BadRequestError8("Invitation already used.");
|
|
12434
12485
|
}
|
|
12435
12486
|
const expired = new Date(invitation.expireAt) < /* @__PURE__ */ new Date();
|
|
12436
12487
|
if (invitation.status === "expired" || expired) {
|
|
12437
|
-
throw new
|
|
12488
|
+
throw new BadRequestError8("Invitation expired.");
|
|
12438
12489
|
}
|
|
12439
12490
|
const email = invitation.email;
|
|
12440
12491
|
const _user = await getUserByEmail(invitation.email);
|
|
12441
12492
|
if (_user) {
|
|
12442
|
-
throw new
|
|
12493
|
+
throw new BadRequestError8(`User already exists: ${email}.`);
|
|
12443
12494
|
}
|
|
12444
12495
|
const hashedPassword = await hashPassword(password);
|
|
12445
12496
|
const user = {
|
|
@@ -12480,21 +12531,21 @@ function useUserService() {
|
|
|
12480
12531
|
try {
|
|
12481
12532
|
const signUp = await _getVerificationById(id);
|
|
12482
12533
|
if (!signUp) {
|
|
12483
|
-
throw new
|
|
12534
|
+
throw new BadRequestError8("Invalid sign up link.");
|
|
12484
12535
|
}
|
|
12485
12536
|
if (signUp.status === "complete") {
|
|
12486
|
-
throw new
|
|
12537
|
+
throw new BadRequestError8(
|
|
12487
12538
|
"You have already an account created using this link."
|
|
12488
12539
|
);
|
|
12489
12540
|
}
|
|
12490
12541
|
const expired = new Date(signUp.expireAt) < /* @__PURE__ */ new Date();
|
|
12491
12542
|
if (signUp.status === "expired" || expired) {
|
|
12492
|
-
throw new
|
|
12543
|
+
throw new BadRequestError8("Sign up link expired.");
|
|
12493
12544
|
}
|
|
12494
12545
|
const email = signUp.email;
|
|
12495
12546
|
const _user = await getUserByEmail(signUp.email);
|
|
12496
12547
|
if (_user) {
|
|
12497
|
-
throw new
|
|
12548
|
+
throw new BadRequestError8(`User already exists: ${email}.`);
|
|
12498
12549
|
}
|
|
12499
12550
|
const hashedPassword = await hashPassword(password);
|
|
12500
12551
|
const user = {
|
|
@@ -12526,7 +12577,7 @@ function useUserService() {
|
|
|
12526
12577
|
throw error;
|
|
12527
12578
|
}
|
|
12528
12579
|
if (newPassword !== passwordConfirmation) {
|
|
12529
|
-
throw new
|
|
12580
|
+
throw new BadRequestError8("Passwords do not match.");
|
|
12530
12581
|
}
|
|
12531
12582
|
let hashedPassword;
|
|
12532
12583
|
try {
|
|
@@ -12540,7 +12591,7 @@ function useUserService() {
|
|
|
12540
12591
|
throw new NotFoundError2("You are using an invalid reset link.");
|
|
12541
12592
|
}
|
|
12542
12593
|
if (otpDoc.status === "used") {
|
|
12543
|
-
throw new
|
|
12594
|
+
throw new BadRequestError8("This link has already been invalidated.");
|
|
12544
12595
|
}
|
|
12545
12596
|
await updateStatusById(id, "used");
|
|
12546
12597
|
return "Successfully reset password.";
|
|
@@ -12550,13 +12601,13 @@ function useUserService() {
|
|
|
12550
12601
|
}
|
|
12551
12602
|
async function updateName(_id, firstName, lastName) {
|
|
12552
12603
|
if (!_id) {
|
|
12553
|
-
throw new
|
|
12604
|
+
throw new BadRequestError8("Invalid user ID");
|
|
12554
12605
|
}
|
|
12555
12606
|
if (!firstName) {
|
|
12556
|
-
throw new
|
|
12607
|
+
throw new BadRequestError8("Invalid firstName");
|
|
12557
12608
|
}
|
|
12558
12609
|
if (!lastName) {
|
|
12559
|
-
throw new
|
|
12610
|
+
throw new BadRequestError8("Invalid lastName");
|
|
12560
12611
|
}
|
|
12561
12612
|
const session = useAtlas6.getClient()?.startSession();
|
|
12562
12613
|
session?.startTransaction();
|
|
@@ -12573,16 +12624,16 @@ function useUserService() {
|
|
|
12573
12624
|
}
|
|
12574
12625
|
async function updateBirthday(_id, month, day, year) {
|
|
12575
12626
|
if (!_id) {
|
|
12576
|
-
throw new
|
|
12627
|
+
throw new BadRequestError8("Invalid user ID");
|
|
12577
12628
|
}
|
|
12578
12629
|
if (!month) {
|
|
12579
|
-
throw new
|
|
12630
|
+
throw new BadRequestError8("Invalid birth month.");
|
|
12580
12631
|
}
|
|
12581
12632
|
if (!day) {
|
|
12582
|
-
throw new
|
|
12633
|
+
throw new BadRequestError8("Invalid birthday.");
|
|
12583
12634
|
}
|
|
12584
12635
|
if (!year) {
|
|
12585
|
-
throw new
|
|
12636
|
+
throw new BadRequestError8("Invalid birth year.");
|
|
12586
12637
|
}
|
|
12587
12638
|
try {
|
|
12588
12639
|
await _updateBirthday({ _id, month, day, year });
|
|
@@ -12654,7 +12705,7 @@ function useUserService() {
|
|
|
12654
12705
|
// src/controllers/user.controller.ts
|
|
12655
12706
|
import {
|
|
12656
12707
|
AppError as AppError2,
|
|
12657
|
-
BadRequestError as
|
|
12708
|
+
BadRequestError as BadRequestError9,
|
|
12658
12709
|
InternalServerError as InternalServerError8
|
|
12659
12710
|
} from "@goweekdays/utils";
|
|
12660
12711
|
import Joi2 from "joi";
|
|
@@ -12680,7 +12731,7 @@ function useUserController() {
|
|
|
12680
12731
|
});
|
|
12681
12732
|
const { error } = validation.validate({ status, search, page });
|
|
12682
12733
|
if (error) {
|
|
12683
|
-
next(new
|
|
12734
|
+
next(new BadRequestError9(error.message));
|
|
12684
12735
|
}
|
|
12685
12736
|
try {
|
|
12686
12737
|
const items = await _getUsers({ status, search, page });
|
|
@@ -12694,12 +12745,12 @@ function useUserController() {
|
|
|
12694
12745
|
const id = req.params.id || "";
|
|
12695
12746
|
const validation = Joi2.string().hex().validate(id);
|
|
12696
12747
|
if (validation.error) {
|
|
12697
|
-
throw new
|
|
12748
|
+
throw new BadRequestError9("Invalid id.");
|
|
12698
12749
|
}
|
|
12699
12750
|
try {
|
|
12700
12751
|
const user = await _getUserById(id);
|
|
12701
12752
|
if (!user) {
|
|
12702
|
-
throw new
|
|
12753
|
+
throw new BadRequestError9("User not found.");
|
|
12703
12754
|
}
|
|
12704
12755
|
res.json(user);
|
|
12705
12756
|
} catch (error) {
|
|
@@ -12716,7 +12767,7 @@ function useUserController() {
|
|
|
12716
12767
|
});
|
|
12717
12768
|
const { error } = validation.validate({ firstName, lastName });
|
|
12718
12769
|
if (error) {
|
|
12719
|
-
next(new
|
|
12770
|
+
next(new BadRequestError9(error.message));
|
|
12720
12771
|
return;
|
|
12721
12772
|
}
|
|
12722
12773
|
try {
|
|
@@ -12739,7 +12790,7 @@ function useUserController() {
|
|
|
12739
12790
|
});
|
|
12740
12791
|
const { error } = validation.validate({ month, day, year });
|
|
12741
12792
|
if (error) {
|
|
12742
|
-
next(new
|
|
12793
|
+
next(new BadRequestError9(error.message));
|
|
12743
12794
|
return;
|
|
12744
12795
|
}
|
|
12745
12796
|
try {
|
|
@@ -12764,7 +12815,7 @@ function useUserController() {
|
|
|
12764
12815
|
});
|
|
12765
12816
|
const { error } = validation.validate({ _id, field, value });
|
|
12766
12817
|
if (error) {
|
|
12767
|
-
next(new
|
|
12818
|
+
next(new BadRequestError9(error.message));
|
|
12768
12819
|
return;
|
|
12769
12820
|
}
|
|
12770
12821
|
try {
|
|
@@ -12785,7 +12836,7 @@ function useUserController() {
|
|
|
12785
12836
|
});
|
|
12786
12837
|
const { error } = validation.validate({ previousProfile });
|
|
12787
12838
|
if (error) {
|
|
12788
|
-
next(new
|
|
12839
|
+
next(new BadRequestError9(error.message));
|
|
12789
12840
|
return;
|
|
12790
12841
|
}
|
|
12791
12842
|
const user = req.headers["user"] ?? "";
|
|
@@ -12826,7 +12877,7 @@ function useUserController() {
|
|
|
12826
12877
|
type
|
|
12827
12878
|
});
|
|
12828
12879
|
if (error) {
|
|
12829
|
-
next(new
|
|
12880
|
+
next(new BadRequestError9(error.message));
|
|
12830
12881
|
return;
|
|
12831
12882
|
}
|
|
12832
12883
|
try {
|
|
@@ -12861,7 +12912,7 @@ function useUserController() {
|
|
|
12861
12912
|
// src/services/auth.service.ts
|
|
12862
12913
|
import {
|
|
12863
12914
|
AppError as AppError3,
|
|
12864
|
-
BadRequestError as
|
|
12915
|
+
BadRequestError as BadRequestError10,
|
|
12865
12916
|
comparePassword,
|
|
12866
12917
|
generateToken,
|
|
12867
12918
|
InternalServerError as InternalServerError9,
|
|
@@ -12872,10 +12923,10 @@ function useAuthService() {
|
|
|
12872
12923
|
const expiresIn = "1m";
|
|
12873
12924
|
async function login({ email, password } = {}) {
|
|
12874
12925
|
if (!email) {
|
|
12875
|
-
throw new
|
|
12926
|
+
throw new BadRequestError10("Email is required");
|
|
12876
12927
|
}
|
|
12877
12928
|
if (!password) {
|
|
12878
|
-
throw new
|
|
12929
|
+
throw new BadRequestError10("Password is required");
|
|
12879
12930
|
}
|
|
12880
12931
|
let _user;
|
|
12881
12932
|
try {
|
|
@@ -12893,13 +12944,13 @@ function useAuthService() {
|
|
|
12893
12944
|
);
|
|
12894
12945
|
}
|
|
12895
12946
|
if (_user.status === "suspended") {
|
|
12896
|
-
throw new
|
|
12947
|
+
throw new BadRequestError10(
|
|
12897
12948
|
"Your account is currently suspended. Please contact support for assistance."
|
|
12898
12949
|
);
|
|
12899
12950
|
}
|
|
12900
12951
|
const isPasswordValid = await comparePassword(password, _user.password);
|
|
12901
12952
|
if (!isPasswordValid) {
|
|
12902
|
-
throw new
|
|
12953
|
+
throw new BadRequestError10("Invalid password");
|
|
12903
12954
|
}
|
|
12904
12955
|
const metadata = { user: _user._id };
|
|
12905
12956
|
let refreshToken2;
|
|
@@ -12910,7 +12961,7 @@ function useAuthService() {
|
|
|
12910
12961
|
options: { expiresIn: "7d" }
|
|
12911
12962
|
});
|
|
12912
12963
|
} catch (error) {
|
|
12913
|
-
throw new
|
|
12964
|
+
throw new BadRequestError10("Error generating refresh token");
|
|
12914
12965
|
}
|
|
12915
12966
|
let accessToken;
|
|
12916
12967
|
try {
|
|
@@ -12920,13 +12971,13 @@ function useAuthService() {
|
|
|
12920
12971
|
options: { expiresIn }
|
|
12921
12972
|
});
|
|
12922
12973
|
} catch (error) {
|
|
12923
|
-
throw new
|
|
12974
|
+
throw new BadRequestError10("Error generating access token");
|
|
12924
12975
|
}
|
|
12925
12976
|
const user = _user._id ?? "";
|
|
12926
12977
|
try {
|
|
12927
12978
|
await useTokenRepo().createToken({ token: refreshToken2, user });
|
|
12928
12979
|
} catch (error) {
|
|
12929
|
-
throw new
|
|
12980
|
+
throw new BadRequestError10("Error creating refresh token");
|
|
12930
12981
|
}
|
|
12931
12982
|
return { accessToken, refreshToken: refreshToken2, id: _user._id };
|
|
12932
12983
|
}
|
|
@@ -12935,7 +12986,7 @@ function useAuthService() {
|
|
|
12935
12986
|
try {
|
|
12936
12987
|
decoded = await jwt.verify(token, REFRESH_TOKEN_SECRET);
|
|
12937
12988
|
} catch (error) {
|
|
12938
|
-
throw new
|
|
12989
|
+
throw new BadRequestError10("Invalid refresh token");
|
|
12939
12990
|
}
|
|
12940
12991
|
let _token;
|
|
12941
12992
|
try {
|
|
@@ -12958,7 +13009,7 @@ function useAuthService() {
|
|
|
12958
13009
|
options: { expiresIn }
|
|
12959
13010
|
});
|
|
12960
13011
|
} catch (error) {
|
|
12961
|
-
throw new
|
|
13012
|
+
throw new BadRequestError10("Error generating access token");
|
|
12962
13013
|
}
|
|
12963
13014
|
return accessToken;
|
|
12964
13015
|
}
|
|
@@ -12994,7 +13045,7 @@ function useAuthService() {
|
|
|
12994
13045
|
import Joi3 from "joi";
|
|
12995
13046
|
import {
|
|
12996
13047
|
AppError as AppError4,
|
|
12997
|
-
BadRequestError as
|
|
13048
|
+
BadRequestError as BadRequestError11,
|
|
12998
13049
|
InternalServerError as InternalServerError10
|
|
12999
13050
|
} from "@goweekdays/utils";
|
|
13000
13051
|
function useAuthController() {
|
|
@@ -13008,7 +13059,7 @@ function useAuthController() {
|
|
|
13008
13059
|
});
|
|
13009
13060
|
const { error } = validation.validate({ email, password });
|
|
13010
13061
|
if (error) {
|
|
13011
|
-
next(new
|
|
13062
|
+
next(new BadRequestError11(error.message));
|
|
13012
13063
|
}
|
|
13013
13064
|
try {
|
|
13014
13065
|
const token = await useAuthService().login({ email, password });
|
|
@@ -13024,7 +13075,7 @@ function useAuthController() {
|
|
|
13024
13075
|
async function refreshToken(req, res, next) {
|
|
13025
13076
|
const refreshToken2 = req.body.token;
|
|
13026
13077
|
if (!refreshToken2) {
|
|
13027
|
-
next(new
|
|
13078
|
+
next(new BadRequestError11("Refresh token is required"));
|
|
13028
13079
|
return;
|
|
13029
13080
|
}
|
|
13030
13081
|
try {
|
|
@@ -13041,7 +13092,7 @@ function useAuthController() {
|
|
|
13041
13092
|
async function logout(req, res, next) {
|
|
13042
13093
|
const token = req.params.id || "";
|
|
13043
13094
|
if (!token) {
|
|
13044
|
-
next(new
|
|
13095
|
+
next(new BadRequestError11("Token is required"));
|
|
13045
13096
|
return;
|
|
13046
13097
|
}
|
|
13047
13098
|
try {
|
|
@@ -13070,7 +13121,7 @@ function useAuthController() {
|
|
|
13070
13121
|
passwordConfirmation
|
|
13071
13122
|
});
|
|
13072
13123
|
if (error) {
|
|
13073
|
-
next(new
|
|
13124
|
+
next(new BadRequestError11(error.message));
|
|
13074
13125
|
return;
|
|
13075
13126
|
}
|
|
13076
13127
|
try {
|
|
@@ -13094,7 +13145,7 @@ function useAuthController() {
|
|
|
13094
13145
|
});
|
|
13095
13146
|
const { error } = validation.validate({ email, referralCode });
|
|
13096
13147
|
if (error) {
|
|
13097
|
-
next(new
|
|
13148
|
+
next(new BadRequestError11(error.message));
|
|
13098
13149
|
return;
|
|
13099
13150
|
}
|
|
13100
13151
|
try {
|
|
@@ -13130,8 +13181,17 @@ var MRole = class {
|
|
|
13130
13181
|
throw new Error("Invalid _id.");
|
|
13131
13182
|
}
|
|
13132
13183
|
}
|
|
13184
|
+
if (typeof value.org === "string") {
|
|
13185
|
+
try {
|
|
13186
|
+
value.org = new ObjectId8(value.org);
|
|
13187
|
+
} catch (error) {
|
|
13188
|
+
throw new Error("Invalid org.");
|
|
13189
|
+
}
|
|
13190
|
+
}
|
|
13191
|
+
this.org = value.org ?? "";
|
|
13133
13192
|
this._id = value._id ?? new ObjectId8();
|
|
13134
13193
|
this.name = value.name ?? "";
|
|
13194
|
+
this.description = value.description ?? "";
|
|
13135
13195
|
this.permissions = value.permissions ?? [];
|
|
13136
13196
|
this.type = value.type ? value.type : "account";
|
|
13137
13197
|
this.status = value.status ?? "active";
|
|
@@ -13151,7 +13211,7 @@ var MRole = class {
|
|
|
13151
13211
|
|
|
13152
13212
|
// src/repositories/role.repository.ts
|
|
13153
13213
|
import {
|
|
13154
|
-
BadRequestError as
|
|
13214
|
+
BadRequestError as BadRequestError12,
|
|
13155
13215
|
InternalServerError as InternalServerError11,
|
|
13156
13216
|
useAtlas as useAtlas7,
|
|
13157
13217
|
paginate as paginate3,
|
|
@@ -13196,7 +13256,7 @@ function useRoleRepo() {
|
|
|
13196
13256
|
logger4.log({ level: "error", message: `${error}` });
|
|
13197
13257
|
const isDuplicated = error.message.includes("duplicate");
|
|
13198
13258
|
if (isDuplicated) {
|
|
13199
|
-
throw new
|
|
13259
|
+
throw new BadRequestError12("Item role already exists");
|
|
13200
13260
|
}
|
|
13201
13261
|
throw new InternalServerError11("Failed to create role.");
|
|
13202
13262
|
}
|
|
@@ -13205,7 +13265,7 @@ function useRoleRepo() {
|
|
|
13205
13265
|
try {
|
|
13206
13266
|
value = new ObjectId9(value);
|
|
13207
13267
|
} catch (error) {
|
|
13208
|
-
throw new
|
|
13268
|
+
throw new BadRequestError12("Invalid user ID.");
|
|
13209
13269
|
}
|
|
13210
13270
|
try {
|
|
13211
13271
|
return await collection.findOne({ user: value });
|
|
@@ -13217,7 +13277,7 @@ function useRoleRepo() {
|
|
|
13217
13277
|
try {
|
|
13218
13278
|
_id = new ObjectId9(_id);
|
|
13219
13279
|
} catch (error) {
|
|
13220
|
-
throw new
|
|
13280
|
+
throw new BadRequestError12("Invalid ID.");
|
|
13221
13281
|
}
|
|
13222
13282
|
try {
|
|
13223
13283
|
return await collection.findOne({ _id });
|
|
@@ -13227,7 +13287,7 @@ function useRoleRepo() {
|
|
|
13227
13287
|
}
|
|
13228
13288
|
async function getRoleByName(name) {
|
|
13229
13289
|
if (!name) {
|
|
13230
|
-
throw new
|
|
13290
|
+
throw new BadRequestError12("Role name is required.");
|
|
13231
13291
|
}
|
|
13232
13292
|
try {
|
|
13233
13293
|
return await collection.findOne({ name });
|
|
@@ -13267,12 +13327,12 @@ function useRoleRepo() {
|
|
|
13267
13327
|
}
|
|
13268
13328
|
async function updateRole(_id, value, session) {
|
|
13269
13329
|
if (!_id) {
|
|
13270
|
-
throw new
|
|
13330
|
+
throw new BadRequestError12("Role ID is required.");
|
|
13271
13331
|
}
|
|
13272
13332
|
try {
|
|
13273
13333
|
_id = new ObjectId9(_id);
|
|
13274
13334
|
} catch (error) {
|
|
13275
|
-
throw new
|
|
13335
|
+
throw new BadRequestError12("Invalid role ID.");
|
|
13276
13336
|
}
|
|
13277
13337
|
if (!value.name) {
|
|
13278
13338
|
delete value.name;
|
|
@@ -13288,14 +13348,14 @@ function useRoleRepo() {
|
|
|
13288
13348
|
throw new InternalServerError11("Failed to update role.");
|
|
13289
13349
|
}
|
|
13290
13350
|
} else {
|
|
13291
|
-
throw new
|
|
13351
|
+
throw new BadRequestError12("No fields to update.");
|
|
13292
13352
|
}
|
|
13293
13353
|
}
|
|
13294
13354
|
async function deleteRole(_id, session) {
|
|
13295
13355
|
try {
|
|
13296
13356
|
_id = new ObjectId9(_id);
|
|
13297
13357
|
} catch (error) {
|
|
13298
|
-
throw new
|
|
13358
|
+
throw new BadRequestError12("Invalid ID.");
|
|
13299
13359
|
}
|
|
13300
13360
|
try {
|
|
13301
13361
|
await collection.deleteOne(
|
|
@@ -13337,7 +13397,8 @@ function useFileService() {
|
|
|
13337
13397
|
secretAccessKey: SPACES_SECRET_KEY,
|
|
13338
13398
|
endpoint: SPACES_ENDPOINT,
|
|
13339
13399
|
region: SPACES_REGION,
|
|
13340
|
-
bucket: SPACES_BUCKET
|
|
13400
|
+
bucket: SPACES_BUCKET,
|
|
13401
|
+
forcePathStyle: true
|
|
13341
13402
|
});
|
|
13342
13403
|
async function createFile(value) {
|
|
13343
13404
|
const session = useAtlas8.getClient()?.startSession();
|
|
@@ -13408,7 +13469,7 @@ function useFileService() {
|
|
|
13408
13469
|
// src/controllers/file.controller.ts
|
|
13409
13470
|
import {
|
|
13410
13471
|
AppError as AppError5,
|
|
13411
|
-
BadRequestError as
|
|
13472
|
+
BadRequestError as BadRequestError13,
|
|
13412
13473
|
InternalServerError as InternalServerError12
|
|
13413
13474
|
} from "@goweekdays/utils";
|
|
13414
13475
|
import Joi4 from "joi";
|
|
@@ -13436,7 +13497,7 @@ function useFileController() {
|
|
|
13436
13497
|
const validation = Joi4.string().required();
|
|
13437
13498
|
const { error } = validation.validate(id);
|
|
13438
13499
|
if (error) {
|
|
13439
|
-
next(new
|
|
13500
|
+
next(new BadRequestError13(error.message));
|
|
13440
13501
|
}
|
|
13441
13502
|
try {
|
|
13442
13503
|
const message = await _deleteFile(id);
|
|
@@ -13534,7 +13595,7 @@ function useRoleService() {
|
|
|
13534
13595
|
|
|
13535
13596
|
// src/controllers/role.controller.ts
|
|
13536
13597
|
import Joi5 from "joi";
|
|
13537
|
-
import { BadRequestError as
|
|
13598
|
+
import { BadRequestError as BadRequestError14 } from "@goweekdays/utils";
|
|
13538
13599
|
function useRoleController() {
|
|
13539
13600
|
const {
|
|
13540
13601
|
createRole: _createRole,
|
|
@@ -13555,7 +13616,7 @@ function useRoleController() {
|
|
|
13555
13616
|
});
|
|
13556
13617
|
const { error } = validation.validate({ name, permissions, type });
|
|
13557
13618
|
if (error) {
|
|
13558
|
-
next(new
|
|
13619
|
+
next(new BadRequestError14(error.message));
|
|
13559
13620
|
return;
|
|
13560
13621
|
}
|
|
13561
13622
|
try {
|
|
@@ -13579,7 +13640,7 @@ function useRoleController() {
|
|
|
13579
13640
|
});
|
|
13580
13641
|
const { error } = validation.validate({ search, page, limit, type });
|
|
13581
13642
|
if (error) {
|
|
13582
|
-
next(new
|
|
13643
|
+
next(new BadRequestError14(error.message));
|
|
13583
13644
|
return;
|
|
13584
13645
|
}
|
|
13585
13646
|
try {
|
|
@@ -13598,7 +13659,7 @@ function useRoleController() {
|
|
|
13598
13659
|
});
|
|
13599
13660
|
const { error } = validation.validate({ userId });
|
|
13600
13661
|
if (error) {
|
|
13601
|
-
next(new
|
|
13662
|
+
next(new BadRequestError14(error.message));
|
|
13602
13663
|
return;
|
|
13603
13664
|
}
|
|
13604
13665
|
try {
|
|
@@ -13616,7 +13677,7 @@ function useRoleController() {
|
|
|
13616
13677
|
});
|
|
13617
13678
|
const { error } = validation.validate({ _id });
|
|
13618
13679
|
if (error) {
|
|
13619
|
-
next(new
|
|
13680
|
+
next(new BadRequestError14(error.message));
|
|
13620
13681
|
return;
|
|
13621
13682
|
}
|
|
13622
13683
|
try {
|
|
@@ -13638,7 +13699,7 @@ function useRoleController() {
|
|
|
13638
13699
|
});
|
|
13639
13700
|
const { error } = validation.validate({ _id, name, permissions });
|
|
13640
13701
|
if (error) {
|
|
13641
|
-
next(new
|
|
13702
|
+
next(new BadRequestError14(error.message));
|
|
13642
13703
|
return;
|
|
13643
13704
|
}
|
|
13644
13705
|
try {
|
|
@@ -13656,7 +13717,7 @@ function useRoleController() {
|
|
|
13656
13717
|
});
|
|
13657
13718
|
const { error } = validation.validate({ _id });
|
|
13658
13719
|
if (error) {
|
|
13659
|
-
next(new
|
|
13720
|
+
next(new BadRequestError14(error.message));
|
|
13660
13721
|
return;
|
|
13661
13722
|
}
|
|
13662
13723
|
try {
|
|
@@ -13695,7 +13756,7 @@ var MEntity = class {
|
|
|
13695
13756
|
// src/repositories/entity.repository.ts
|
|
13696
13757
|
import { ObjectId as ObjectId11 } from "mongodb";
|
|
13697
13758
|
import {
|
|
13698
|
-
BadRequestError as
|
|
13759
|
+
BadRequestError as BadRequestError15,
|
|
13699
13760
|
InternalServerError as InternalServerError13,
|
|
13700
13761
|
logger as logger6,
|
|
13701
13762
|
paginate as paginate4,
|
|
@@ -13733,7 +13794,7 @@ function useEntityRepo() {
|
|
|
13733
13794
|
logger6.log({ level: "error", message: `${error}` });
|
|
13734
13795
|
const isDuplicated = error.message.includes("duplicate");
|
|
13735
13796
|
if (isDuplicated) {
|
|
13736
|
-
throw new
|
|
13797
|
+
throw new BadRequestError15("Entity name already exists.");
|
|
13737
13798
|
}
|
|
13738
13799
|
throw new InternalServerError13("Failed to create entity.");
|
|
13739
13800
|
}
|
|
@@ -13767,14 +13828,14 @@ function useEntityRepo() {
|
|
|
13767
13828
|
async function updateEntityFieldById({ _id, field, value } = {}, session) {
|
|
13768
13829
|
const allowedFields = ["name"];
|
|
13769
13830
|
if (!allowedFields.includes(field)) {
|
|
13770
|
-
throw new
|
|
13831
|
+
throw new BadRequestError15(
|
|
13771
13832
|
`Field "${field}" is not allowed to be updated.`
|
|
13772
13833
|
);
|
|
13773
13834
|
}
|
|
13774
13835
|
try {
|
|
13775
13836
|
_id = new ObjectId11(_id);
|
|
13776
13837
|
} catch (error) {
|
|
13777
|
-
throw new
|
|
13838
|
+
throw new BadRequestError15("Invalid ID.");
|
|
13778
13839
|
}
|
|
13779
13840
|
try {
|
|
13780
13841
|
await collection.updateOne(
|
|
@@ -13792,7 +13853,7 @@ function useEntityRepo() {
|
|
|
13792
13853
|
try {
|
|
13793
13854
|
_id = new ObjectId11(_id);
|
|
13794
13855
|
} catch (error) {
|
|
13795
|
-
throw new
|
|
13856
|
+
throw new BadRequestError15("Invalid entity ID.");
|
|
13796
13857
|
}
|
|
13797
13858
|
try {
|
|
13798
13859
|
return await collection.updateOne(
|
|
@@ -13860,7 +13921,7 @@ function useEntityService() {
|
|
|
13860
13921
|
|
|
13861
13922
|
// src/controllers/entity.controller.ts
|
|
13862
13923
|
import Joi6 from "joi";
|
|
13863
|
-
import { BadRequestError as
|
|
13924
|
+
import { BadRequestError as BadRequestError16 } from "@goweekdays/utils";
|
|
13864
13925
|
function useEntityController() {
|
|
13865
13926
|
const {
|
|
13866
13927
|
createEntity: _createEntity,
|
|
@@ -13882,7 +13943,7 @@ function useEntityController() {
|
|
|
13882
13943
|
});
|
|
13883
13944
|
const { error } = validation.validate(value);
|
|
13884
13945
|
if (error) {
|
|
13885
|
-
next(new
|
|
13946
|
+
next(new BadRequestError16(error.message));
|
|
13886
13947
|
return;
|
|
13887
13948
|
}
|
|
13888
13949
|
try {
|
|
@@ -13906,7 +13967,7 @@ function useEntityController() {
|
|
|
13906
13967
|
});
|
|
13907
13968
|
const { error } = validation.validate(req.query);
|
|
13908
13969
|
if (error) {
|
|
13909
|
-
next(new
|
|
13970
|
+
next(new BadRequestError16(error.message));
|
|
13910
13971
|
return;
|
|
13911
13972
|
}
|
|
13912
13973
|
try {
|
|
@@ -13931,7 +13992,7 @@ function useEntityController() {
|
|
|
13931
13992
|
});
|
|
13932
13993
|
const { error } = validation.validate({ id, field, value });
|
|
13933
13994
|
if (error) {
|
|
13934
|
-
next(new
|
|
13995
|
+
next(new BadRequestError16(error.message));
|
|
13935
13996
|
return;
|
|
13936
13997
|
}
|
|
13937
13998
|
try {
|
|
@@ -13950,7 +14011,7 @@ function useEntityController() {
|
|
|
13950
14011
|
});
|
|
13951
14012
|
const { error } = validation.validate({ id });
|
|
13952
14013
|
if (error) {
|
|
13953
|
-
next(new
|
|
14014
|
+
next(new BadRequestError16(error.message));
|
|
13954
14015
|
return;
|
|
13955
14016
|
}
|
|
13956
14017
|
try {
|
|
@@ -13987,7 +14048,7 @@ var MWorkflow = class {
|
|
|
13987
14048
|
// src/repositories/workflow.repository.ts
|
|
13988
14049
|
import { ObjectId as ObjectId13 } from "mongodb";
|
|
13989
14050
|
import {
|
|
13990
|
-
BadRequestError as
|
|
14051
|
+
BadRequestError as BadRequestError17,
|
|
13991
14052
|
InternalServerError as InternalServerError15,
|
|
13992
14053
|
logger as logger7,
|
|
13993
14054
|
paginate as paginate5,
|
|
@@ -14022,7 +14083,7 @@ function useWorkflowRepo() {
|
|
|
14022
14083
|
} catch (error) {
|
|
14023
14084
|
const duplicated = error.message.includes("duplicate");
|
|
14024
14085
|
if (duplicated) {
|
|
14025
|
-
throw new
|
|
14086
|
+
throw new BadRequestError17("Workflow name already exists.");
|
|
14026
14087
|
}
|
|
14027
14088
|
throw new InternalServerError15("Failed to create workflow.");
|
|
14028
14089
|
}
|
|
@@ -14057,7 +14118,7 @@ function useWorkflowRepo() {
|
|
|
14057
14118
|
try {
|
|
14058
14119
|
_id = new ObjectId13(_id);
|
|
14059
14120
|
} catch (error) {
|
|
14060
|
-
throw new
|
|
14121
|
+
throw new BadRequestError17("Invalid workflow ID.");
|
|
14061
14122
|
}
|
|
14062
14123
|
try {
|
|
14063
14124
|
return await collection.findOne({ _id });
|
|
@@ -14068,14 +14129,14 @@ function useWorkflowRepo() {
|
|
|
14068
14129
|
async function updateWorkflowFieldById({ _id, field, value } = {}, session) {
|
|
14069
14130
|
const allowedFields = ["name"];
|
|
14070
14131
|
if (!allowedFields.includes(field)) {
|
|
14071
|
-
throw new
|
|
14132
|
+
throw new BadRequestError17(
|
|
14072
14133
|
`Field "${field}" is not allowed to be updated.`
|
|
14073
14134
|
);
|
|
14074
14135
|
}
|
|
14075
14136
|
try {
|
|
14076
14137
|
_id = new ObjectId13(_id);
|
|
14077
14138
|
} catch (error) {
|
|
14078
|
-
throw new
|
|
14139
|
+
throw new BadRequestError17("Invalid ID.");
|
|
14079
14140
|
}
|
|
14080
14141
|
try {
|
|
14081
14142
|
await collection.updateOne(
|
|
@@ -14093,7 +14154,7 @@ function useWorkflowRepo() {
|
|
|
14093
14154
|
try {
|
|
14094
14155
|
_id = new ObjectId13(_id);
|
|
14095
14156
|
} catch (error) {
|
|
14096
|
-
throw new
|
|
14157
|
+
throw new BadRequestError17("Invalid entity ID.");
|
|
14097
14158
|
}
|
|
14098
14159
|
try {
|
|
14099
14160
|
return await collection.updateOne(
|
|
@@ -14380,7 +14441,7 @@ var MCapBldgAct = class {
|
|
|
14380
14441
|
// src/repositories/cap-bldg-act.repository.ts
|
|
14381
14442
|
import { ObjectId as ObjectId15 } from "mongodb";
|
|
14382
14443
|
import {
|
|
14383
|
-
BadRequestError as
|
|
14444
|
+
BadRequestError as BadRequestError18,
|
|
14384
14445
|
InternalServerError as InternalServerError16,
|
|
14385
14446
|
logger as logger8,
|
|
14386
14447
|
paginate as paginate6,
|
|
@@ -14424,7 +14485,7 @@ function useCapBldgActRepo() {
|
|
|
14424
14485
|
logger8.log({ level: "error", message: `${error}` });
|
|
14425
14486
|
const isDuplicated = error.message.includes("duplicate");
|
|
14426
14487
|
if (isDuplicated) {
|
|
14427
|
-
throw new
|
|
14488
|
+
throw new BadRequestError18("CapBldgAct name already exists.");
|
|
14428
14489
|
}
|
|
14429
14490
|
throw new InternalServerError16("Failed to create CapBldgAct.");
|
|
14430
14491
|
}
|
|
@@ -14433,7 +14494,7 @@ function useCapBldgActRepo() {
|
|
|
14433
14494
|
try {
|
|
14434
14495
|
_id = new ObjectId15(_id);
|
|
14435
14496
|
} catch (error) {
|
|
14436
|
-
throw new
|
|
14497
|
+
throw new BadRequestError18("Invalid CapBldgAct ID.");
|
|
14437
14498
|
}
|
|
14438
14499
|
try {
|
|
14439
14500
|
await collection.updateOne(
|
|
@@ -14452,7 +14513,7 @@ function useCapBldgActRepo() {
|
|
|
14452
14513
|
try {
|
|
14453
14514
|
_id = new ObjectId15(_id);
|
|
14454
14515
|
} catch (error) {
|
|
14455
|
-
throw new
|
|
14516
|
+
throw new BadRequestError18("Invalid CapBldgAct ID.");
|
|
14456
14517
|
}
|
|
14457
14518
|
try {
|
|
14458
14519
|
await collection.updateOne(
|
|
@@ -14473,7 +14534,7 @@ function useCapBldgActRepo() {
|
|
|
14473
14534
|
try {
|
|
14474
14535
|
_id = new ObjectId15(_id);
|
|
14475
14536
|
} catch (error) {
|
|
14476
|
-
throw new
|
|
14537
|
+
throw new BadRequestError18("Invalid CapBldgAct ID.");
|
|
14477
14538
|
}
|
|
14478
14539
|
try {
|
|
14479
14540
|
await collection.updateOne(
|
|
@@ -14494,7 +14555,7 @@ function useCapBldgActRepo() {
|
|
|
14494
14555
|
try {
|
|
14495
14556
|
_id = new ObjectId15(_id);
|
|
14496
14557
|
} catch (error) {
|
|
14497
|
-
throw new
|
|
14558
|
+
throw new BadRequestError18("Invalid CapBldgAct ID.");
|
|
14498
14559
|
}
|
|
14499
14560
|
try {
|
|
14500
14561
|
return await collection.findOne({ _id });
|
|
@@ -14558,14 +14619,14 @@ function useCapBldgActRepo() {
|
|
|
14558
14619
|
"status"
|
|
14559
14620
|
];
|
|
14560
14621
|
if (!allowedFields.includes(field)) {
|
|
14561
|
-
throw new
|
|
14622
|
+
throw new BadRequestError18(
|
|
14562
14623
|
`Field "${field}" is not allowed to be updated.`
|
|
14563
14624
|
);
|
|
14564
14625
|
}
|
|
14565
14626
|
try {
|
|
14566
14627
|
_id = new ObjectId15(_id);
|
|
14567
14628
|
} catch (error) {
|
|
14568
|
-
throw new
|
|
14629
|
+
throw new BadRequestError18("Invalid ID.");
|
|
14569
14630
|
}
|
|
14570
14631
|
try {
|
|
14571
14632
|
await collection.updateOne(
|
|
@@ -14583,7 +14644,7 @@ function useCapBldgActRepo() {
|
|
|
14583
14644
|
try {
|
|
14584
14645
|
_id = new ObjectId15(_id);
|
|
14585
14646
|
} catch (error) {
|
|
14586
|
-
throw new
|
|
14647
|
+
throw new BadRequestError18("Invalid CapBldgAct ID.");
|
|
14587
14648
|
}
|
|
14588
14649
|
try {
|
|
14589
14650
|
return await collection.updateOne(
|
|
@@ -14751,7 +14812,7 @@ function useCapBldgActService() {
|
|
|
14751
14812
|
|
|
14752
14813
|
// src/controllers/cap-bldg-act.controller.ts
|
|
14753
14814
|
import Joi8 from "joi";
|
|
14754
|
-
import { BadRequestError as
|
|
14815
|
+
import { BadRequestError as BadRequestError19 } from "@goweekdays/utils";
|
|
14755
14816
|
function useCapBldgActController() {
|
|
14756
14817
|
const {
|
|
14757
14818
|
createCapBldgAct: _createCapBldgAct,
|
|
@@ -14778,7 +14839,7 @@ function useCapBldgActController() {
|
|
|
14778
14839
|
});
|
|
14779
14840
|
const { error } = validation.validate(value);
|
|
14780
14841
|
if (error) {
|
|
14781
|
-
next(new
|
|
14842
|
+
next(new BadRequestError19(error.message));
|
|
14782
14843
|
return;
|
|
14783
14844
|
}
|
|
14784
14845
|
try {
|
|
@@ -14804,7 +14865,7 @@ function useCapBldgActController() {
|
|
|
14804
14865
|
});
|
|
14805
14866
|
const { error } = validation.validate({ ...value, id });
|
|
14806
14867
|
if (error) {
|
|
14807
|
-
next(new
|
|
14868
|
+
next(new BadRequestError19(error.message));
|
|
14808
14869
|
return;
|
|
14809
14870
|
}
|
|
14810
14871
|
try {
|
|
@@ -14857,7 +14918,7 @@ function useCapBldgActController() {
|
|
|
14857
14918
|
});
|
|
14858
14919
|
const { error } = validation.validate({ ...value, id });
|
|
14859
14920
|
if (error) {
|
|
14860
|
-
next(new
|
|
14921
|
+
next(new BadRequestError19(error.message));
|
|
14861
14922
|
return;
|
|
14862
14923
|
}
|
|
14863
14924
|
try {
|
|
@@ -14887,7 +14948,7 @@ function useCapBldgActController() {
|
|
|
14887
14948
|
});
|
|
14888
14949
|
const { error } = validation.validate({ ...value, id });
|
|
14889
14950
|
if (error) {
|
|
14890
|
-
next(new
|
|
14951
|
+
next(new BadRequestError19(error.message));
|
|
14891
14952
|
return;
|
|
14892
14953
|
}
|
|
14893
14954
|
try {
|
|
@@ -14913,7 +14974,7 @@ function useCapBldgActController() {
|
|
|
14913
14974
|
});
|
|
14914
14975
|
const { error } = validation.validate(req.query);
|
|
14915
14976
|
if (error) {
|
|
14916
|
-
next(new
|
|
14977
|
+
next(new BadRequestError19(error.message));
|
|
14917
14978
|
return;
|
|
14918
14979
|
}
|
|
14919
14980
|
try {
|
|
@@ -14931,7 +14992,7 @@ function useCapBldgActController() {
|
|
|
14931
14992
|
});
|
|
14932
14993
|
const { error } = validation.validate({ id });
|
|
14933
14994
|
if (error) {
|
|
14934
|
-
next(new
|
|
14995
|
+
next(new BadRequestError19(error.message));
|
|
14935
14996
|
return;
|
|
14936
14997
|
}
|
|
14937
14998
|
try {
|
|
@@ -14963,7 +15024,7 @@ function useCapBldgActController() {
|
|
|
14963
15024
|
});
|
|
14964
15025
|
const { error } = validation.validate({ _id, field, value });
|
|
14965
15026
|
if (error) {
|
|
14966
|
-
next(new
|
|
15027
|
+
next(new BadRequestError19(error.message));
|
|
14967
15028
|
return;
|
|
14968
15029
|
}
|
|
14969
15030
|
try {
|
|
@@ -14987,7 +15048,7 @@ function useCapBldgActController() {
|
|
|
14987
15048
|
});
|
|
14988
15049
|
const { error } = validation.validate({ id, field });
|
|
14989
15050
|
if (error) {
|
|
14990
|
-
next(new
|
|
15051
|
+
next(new BadRequestError19(error.message));
|
|
14991
15052
|
return;
|
|
14992
15053
|
}
|
|
14993
15054
|
try {
|
|
@@ -15005,7 +15066,7 @@ function useCapBldgActController() {
|
|
|
15005
15066
|
const validation = Joi8.string().required();
|
|
15006
15067
|
const { error } = validation.validate(id);
|
|
15007
15068
|
if (error) {
|
|
15008
|
-
next(new
|
|
15069
|
+
next(new BadRequestError19(error.message));
|
|
15009
15070
|
}
|
|
15010
15071
|
try {
|
|
15011
15072
|
const message = await _deleteAttachment(attachment, id, field);
|
|
@@ -15154,7 +15215,7 @@ function useCommentService() {
|
|
|
15154
15215
|
|
|
15155
15216
|
// src/controllers/comment.controller.ts
|
|
15156
15217
|
import Joi9 from "joi";
|
|
15157
|
-
import { BadRequestError as
|
|
15218
|
+
import { BadRequestError as BadRequestError20 } from "@goweekdays/utils";
|
|
15158
15219
|
function useCommentController() {
|
|
15159
15220
|
const { addComment: _addComment, getComments: _getComments } = useCommentService();
|
|
15160
15221
|
async function addComment(req, res, next) {
|
|
@@ -15168,7 +15229,7 @@ function useCommentController() {
|
|
|
15168
15229
|
});
|
|
15169
15230
|
const { error } = validation.validate(value);
|
|
15170
15231
|
if (error) {
|
|
15171
|
-
next(new
|
|
15232
|
+
next(new BadRequestError20(error.message));
|
|
15172
15233
|
return;
|
|
15173
15234
|
}
|
|
15174
15235
|
try {
|
|
@@ -15195,7 +15256,7 @@ function useCommentController() {
|
|
|
15195
15256
|
});
|
|
15196
15257
|
const { error } = validation.validate({ page, document: document2 });
|
|
15197
15258
|
if (error) {
|
|
15198
|
-
next(new
|
|
15259
|
+
next(new BadRequestError20(error.message));
|
|
15199
15260
|
return;
|
|
15200
15261
|
}
|
|
15201
15262
|
try {
|
|
@@ -15214,24 +15275,34 @@ function useCommentController() {
|
|
|
15214
15275
|
}
|
|
15215
15276
|
|
|
15216
15277
|
// src/models/subscription.model.ts
|
|
15217
|
-
import { BadRequestError as
|
|
15278
|
+
import { BadRequestError as BadRequestError21 } from "@goweekdays/utils";
|
|
15218
15279
|
import { ObjectId as ObjectId18 } from "mongodb";
|
|
15219
15280
|
function MSubscription(value) {
|
|
15220
15281
|
if (value._id) {
|
|
15221
15282
|
try {
|
|
15222
15283
|
value._id = new ObjectId18(value._id);
|
|
15223
15284
|
} catch (error) {
|
|
15224
|
-
throw new
|
|
15285
|
+
throw new BadRequestError21("Invalid ID.");
|
|
15225
15286
|
}
|
|
15226
15287
|
}
|
|
15227
|
-
|
|
15228
|
-
|
|
15229
|
-
|
|
15230
|
-
|
|
15288
|
+
if (value.user) {
|
|
15289
|
+
try {
|
|
15290
|
+
value.user = new ObjectId18(value.user);
|
|
15291
|
+
} catch (error) {
|
|
15292
|
+
throw new BadRequestError21("Invalid user ID.");
|
|
15293
|
+
}
|
|
15294
|
+
}
|
|
15295
|
+
if (value.org) {
|
|
15296
|
+
try {
|
|
15297
|
+
value.org = new ObjectId18(value.org);
|
|
15298
|
+
} catch (error) {
|
|
15299
|
+
throw new BadRequestError21("Invalid org ID.");
|
|
15300
|
+
}
|
|
15231
15301
|
}
|
|
15232
15302
|
return {
|
|
15233
15303
|
_id: value._id,
|
|
15234
|
-
user: value.user,
|
|
15304
|
+
user: value.user ?? "",
|
|
15305
|
+
org: value.org ?? "",
|
|
15235
15306
|
subscriptionId: value.subscriptionId,
|
|
15236
15307
|
status: "active",
|
|
15237
15308
|
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -15241,12 +15312,12 @@ function MSubscription(value) {
|
|
|
15241
15312
|
}
|
|
15242
15313
|
|
|
15243
15314
|
// src/repositories/subscription.repository.ts
|
|
15244
|
-
import { BadRequestError as
|
|
15315
|
+
import { BadRequestError as BadRequestError22, logger as logger10, paginate as paginate8, useAtlas as useAtlas14 } from "@goweekdays/utils";
|
|
15245
15316
|
import { ObjectId as ObjectId19 } from "mongodb";
|
|
15246
15317
|
function useSubscriptionRepo() {
|
|
15247
15318
|
const db = useAtlas14.getDb();
|
|
15248
15319
|
if (!db) {
|
|
15249
|
-
throw new
|
|
15320
|
+
throw new BadRequestError22("Unable to connect to server.");
|
|
15250
15321
|
}
|
|
15251
15322
|
const collection = db.collection("subscriptions");
|
|
15252
15323
|
async function createIndex() {
|
|
@@ -15257,56 +15328,56 @@ function useSubscriptionRepo() {
|
|
|
15257
15328
|
{ status: 1 }
|
|
15258
15329
|
]);
|
|
15259
15330
|
} catch (error) {
|
|
15260
|
-
throw new
|
|
15331
|
+
throw new BadRequestError22("Failed to create index on subscription.");
|
|
15261
15332
|
}
|
|
15262
15333
|
}
|
|
15263
15334
|
async function createUniqueIndex() {
|
|
15264
15335
|
try {
|
|
15265
15336
|
await collection.createIndex({ user: 1, status: 1 }, { unique: true });
|
|
15266
15337
|
} catch (error) {
|
|
15267
|
-
throw new
|
|
15338
|
+
throw new BadRequestError22(
|
|
15268
15339
|
"Failed to create unique index on subscription."
|
|
15269
15340
|
);
|
|
15270
15341
|
}
|
|
15271
15342
|
}
|
|
15272
|
-
async function add(value) {
|
|
15343
|
+
async function add(value, session) {
|
|
15273
15344
|
try {
|
|
15274
15345
|
value = MSubscription(value);
|
|
15275
|
-
const res = await collection.insertOne(value);
|
|
15346
|
+
const res = await collection.insertOne(value, { session });
|
|
15276
15347
|
return res.insertedId;
|
|
15277
15348
|
} catch (error) {
|
|
15278
|
-
throw new
|
|
15349
|
+
throw new BadRequestError22("Failed to create subscription.");
|
|
15279
15350
|
}
|
|
15280
15351
|
}
|
|
15281
15352
|
async function getById(_id) {
|
|
15282
15353
|
try {
|
|
15283
15354
|
_id = new ObjectId19(_id);
|
|
15284
15355
|
} catch (error) {
|
|
15285
|
-
throw new
|
|
15356
|
+
throw new BadRequestError22("Invalid ID.");
|
|
15286
15357
|
}
|
|
15287
15358
|
try {
|
|
15288
15359
|
return await collection.findOne({ _id });
|
|
15289
15360
|
} catch (error) {
|
|
15290
|
-
throw new
|
|
15361
|
+
throw new BadRequestError22("Failed to get subscription by ID.");
|
|
15291
15362
|
}
|
|
15292
15363
|
}
|
|
15293
15364
|
async function getByUserId(user) {
|
|
15294
15365
|
try {
|
|
15295
15366
|
user = new ObjectId19(user);
|
|
15296
15367
|
} catch (error) {
|
|
15297
|
-
throw new
|
|
15368
|
+
throw new BadRequestError22("Invalid user ID.");
|
|
15298
15369
|
}
|
|
15299
15370
|
try {
|
|
15300
15371
|
return await collection.findOne({ user });
|
|
15301
15372
|
} catch (error) {
|
|
15302
|
-
throw new
|
|
15373
|
+
throw new BadRequestError22("Failed to get subscription by ID.");
|
|
15303
15374
|
}
|
|
15304
15375
|
}
|
|
15305
15376
|
async function getBySubscriptionId(subscriptionId) {
|
|
15306
15377
|
try {
|
|
15307
15378
|
return await collection.findOne({ subscriptionId });
|
|
15308
15379
|
} catch (error) {
|
|
15309
|
-
throw new
|
|
15380
|
+
throw new BadRequestError22(
|
|
15310
15381
|
"Failed to get subscription by subscription ID."
|
|
15311
15382
|
);
|
|
15312
15383
|
}
|
|
@@ -15342,13 +15413,13 @@ function useSubscriptionRepo() {
|
|
|
15342
15413
|
try {
|
|
15343
15414
|
_id = new ObjectId19(_id);
|
|
15344
15415
|
} catch (error) {
|
|
15345
|
-
throw new
|
|
15416
|
+
throw new BadRequestError22("Invalid ID.");
|
|
15346
15417
|
}
|
|
15347
15418
|
try {
|
|
15348
15419
|
await collection.updateOne({ _id }, { $set: { status } });
|
|
15349
15420
|
return "Successfully updated subscription status.";
|
|
15350
15421
|
} catch (error) {
|
|
15351
|
-
throw new
|
|
15422
|
+
throw new BadRequestError22("Failed to update subscription status.");
|
|
15352
15423
|
}
|
|
15353
15424
|
}
|
|
15354
15425
|
return {
|
|
@@ -15364,7 +15435,7 @@ function useSubscriptionRepo() {
|
|
|
15364
15435
|
}
|
|
15365
15436
|
|
|
15366
15437
|
// src/services/subscription.service.ts
|
|
15367
|
-
import { BadRequestError as
|
|
15438
|
+
import { BadRequestError as BadRequestError30, useAtlas as useAtlas18 } from "@goweekdays/utils";
|
|
15368
15439
|
|
|
15369
15440
|
// node_modules/axios/lib/helpers/bind.js
|
|
15370
15441
|
function bind(fn, thisArg) {
|
|
@@ -18667,188 +18738,1591 @@ var {
|
|
|
18667
18738
|
mergeConfig: mergeConfig2
|
|
18668
18739
|
} = axios_default;
|
|
18669
18740
|
|
|
18670
|
-
// src/services/
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
|
|
18741
|
+
// src/services/xendit.service.ts
|
|
18742
|
+
import { BadRequestError as BadRequestError23 } from "@goweekdays/utils";
|
|
18743
|
+
import { ObjectId as ObjectId20 } from "mongodb";
|
|
18744
|
+
function useXenditService() {
|
|
18745
|
+
const basicAuth = Buffer.from(`${XENDIT_SECRET_KEY}:`).toString("base64");
|
|
18746
|
+
const axios2 = axios_default.create({
|
|
18747
|
+
baseURL: XENDIT_BASE_URL,
|
|
18748
|
+
headers: {
|
|
18749
|
+
"Content-Type": "application/json",
|
|
18750
|
+
Authorization: `Basic ${basicAuth}`
|
|
18751
|
+
}
|
|
18752
|
+
});
|
|
18753
|
+
async function createCustomer({
|
|
18754
|
+
mobile_number = "",
|
|
18755
|
+
email = "",
|
|
18756
|
+
type = "INDIVIDUAL",
|
|
18757
|
+
given_names = "",
|
|
18758
|
+
surname = ""
|
|
18759
|
+
} = {}) {
|
|
18674
18760
|
try {
|
|
18675
|
-
const
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18761
|
+
const res = await axios2.post("/customers", {
|
|
18762
|
+
reference_id: new ObjectId20().toString(),
|
|
18763
|
+
mobile_number,
|
|
18764
|
+
email,
|
|
18765
|
+
type,
|
|
18766
|
+
individual_detail: {
|
|
18767
|
+
given_names,
|
|
18768
|
+
surname
|
|
18769
|
+
}
|
|
18770
|
+
});
|
|
18771
|
+
return res.data;
|
|
18680
18772
|
} catch (error) {
|
|
18681
|
-
throw
|
|
18773
|
+
throw new BadRequestError23("Failed to create customer.");
|
|
18682
18774
|
}
|
|
18683
18775
|
}
|
|
18684
|
-
async function
|
|
18776
|
+
async function linkPaymentMethodEWallet({
|
|
18777
|
+
customerId = "",
|
|
18778
|
+
type = "GCASH",
|
|
18779
|
+
success_return_url = `${APP_ACCOUNT}/payment-methods`,
|
|
18780
|
+
failure_return_url = `${APP_ACCOUNT}/payment-methods`,
|
|
18781
|
+
cancel_return_url = `${APP_ACCOUNT}/payment-methods`
|
|
18782
|
+
} = {}) {
|
|
18685
18783
|
try {
|
|
18686
|
-
const
|
|
18687
|
-
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
18693
|
-
|
|
18694
|
-
|
|
18695
|
-
|
|
18784
|
+
const res = await axios2.post("/v2/payment_methods", {
|
|
18785
|
+
type: "EWALLET",
|
|
18786
|
+
reusability: "MULTIPLE_USE",
|
|
18787
|
+
customer_id: customerId,
|
|
18788
|
+
ewallet: {
|
|
18789
|
+
channel_code: type,
|
|
18790
|
+
channel_properties: {
|
|
18791
|
+
success_return_url,
|
|
18792
|
+
failure_return_url,
|
|
18793
|
+
cancel_return_url
|
|
18696
18794
|
}
|
|
18697
18795
|
}
|
|
18698
|
-
);
|
|
18699
|
-
return
|
|
18796
|
+
});
|
|
18797
|
+
return res.data;
|
|
18798
|
+
} catch (error) {
|
|
18799
|
+
throw new BadRequestError23("Failed to initiate GCash linking.");
|
|
18800
|
+
}
|
|
18801
|
+
}
|
|
18802
|
+
async function linkPaymentMethodCard({
|
|
18803
|
+
success_return_url = `${APP_ACCOUNT}/payment-methods`,
|
|
18804
|
+
failure_return_url = `${APP_ACCOUNT}/payment-methods`,
|
|
18805
|
+
card_number = "",
|
|
18806
|
+
expiry_month = "",
|
|
18807
|
+
expiry_year = "",
|
|
18808
|
+
cvv = "",
|
|
18809
|
+
cardholder_name = "",
|
|
18810
|
+
currency = "PHP"
|
|
18811
|
+
} = {}) {
|
|
18812
|
+
try {
|
|
18813
|
+
const res = await axios2.post("/v2/payment_methods", {
|
|
18814
|
+
type: "CARD",
|
|
18815
|
+
card: {
|
|
18816
|
+
currency,
|
|
18817
|
+
channel_properties: {
|
|
18818
|
+
skip_three_d_secure: true,
|
|
18819
|
+
success_return_url,
|
|
18820
|
+
failure_return_url
|
|
18821
|
+
},
|
|
18822
|
+
card_information: {
|
|
18823
|
+
card_number,
|
|
18824
|
+
expiry_month,
|
|
18825
|
+
expiry_year,
|
|
18826
|
+
cvv,
|
|
18827
|
+
cardholder_name
|
|
18828
|
+
}
|
|
18829
|
+
},
|
|
18830
|
+
reusability: "MULTIPLE_USE",
|
|
18831
|
+
description: "Linking card to GoWeekdays account."
|
|
18832
|
+
});
|
|
18833
|
+
return res.data;
|
|
18700
18834
|
} catch (error) {
|
|
18701
|
-
throw new
|
|
18835
|
+
throw new BadRequestError23("Failed to initiate card linking..");
|
|
18702
18836
|
}
|
|
18703
18837
|
}
|
|
18704
|
-
async function
|
|
18838
|
+
async function eWalletSubsequentPayment({
|
|
18839
|
+
amount = 0,
|
|
18840
|
+
currency = "PHP",
|
|
18841
|
+
payment_method_id = "",
|
|
18842
|
+
customer_id = "",
|
|
18843
|
+
description = ""
|
|
18844
|
+
} = {}) {
|
|
18705
18845
|
try {
|
|
18706
|
-
const
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
|
|
18710
|
-
|
|
18711
|
-
|
|
18712
|
-
|
|
18713
|
-
|
|
18846
|
+
const res = await axios2.post("/payment_requests", {
|
|
18847
|
+
amount,
|
|
18848
|
+
currency,
|
|
18849
|
+
payment_method_id,
|
|
18850
|
+
customer_id,
|
|
18851
|
+
description
|
|
18852
|
+
});
|
|
18853
|
+
return res.data;
|
|
18854
|
+
} catch (error) {
|
|
18855
|
+
console.log(error);
|
|
18856
|
+
throw new BadRequestError23(
|
|
18857
|
+
"Failed to initiate GCash linking and payment request."
|
|
18858
|
+
);
|
|
18859
|
+
}
|
|
18860
|
+
}
|
|
18861
|
+
async function initGCashLinkingAndPaymentRequest({
|
|
18862
|
+
amount = 0,
|
|
18863
|
+
currency = "PHP",
|
|
18864
|
+
countryCode = "PH",
|
|
18865
|
+
customerId = "",
|
|
18866
|
+
success_return_url = `${APP_MAIN}/checkout/success`,
|
|
18867
|
+
failure_return_url = `${APP_MAIN}/checkout/failed`
|
|
18868
|
+
} = {}) {
|
|
18869
|
+
try {
|
|
18870
|
+
const res = await axios2.post("/payment_requests", {
|
|
18871
|
+
amount,
|
|
18872
|
+
currency,
|
|
18873
|
+
country: countryCode,
|
|
18874
|
+
customer_id: customerId,
|
|
18875
|
+
payment_method: {
|
|
18876
|
+
type: "EWALLET",
|
|
18877
|
+
ewallet: {
|
|
18878
|
+
channel_code: "GCASH",
|
|
18879
|
+
channel_properties: {
|
|
18880
|
+
success_return_url,
|
|
18881
|
+
failure_return_url
|
|
18882
|
+
}
|
|
18883
|
+
},
|
|
18884
|
+
reusability: "MULTIPLE_USE"
|
|
18714
18885
|
}
|
|
18886
|
+
});
|
|
18887
|
+
return res.data;
|
|
18888
|
+
} catch (error) {
|
|
18889
|
+
console.log(error);
|
|
18890
|
+
throw new BadRequestError23(
|
|
18891
|
+
"Failed to initiate GCash linking and payment request."
|
|
18715
18892
|
);
|
|
18716
|
-
|
|
18893
|
+
}
|
|
18894
|
+
}
|
|
18895
|
+
async function initSubscription({
|
|
18896
|
+
customer = "",
|
|
18897
|
+
currency = "PHP",
|
|
18898
|
+
amount = 0,
|
|
18899
|
+
paymentMethod = "",
|
|
18900
|
+
description = "",
|
|
18901
|
+
interval = "MONTH"
|
|
18902
|
+
} = {}) {
|
|
18903
|
+
try {
|
|
18904
|
+
const res = await axios2.post("/recurring/plans", {
|
|
18905
|
+
reference_id: new ObjectId20().toString(),
|
|
18906
|
+
customer_id: customer,
|
|
18907
|
+
recurring_action: "PAYMENT",
|
|
18908
|
+
currency,
|
|
18909
|
+
amount,
|
|
18910
|
+
payment_methods: [
|
|
18911
|
+
{
|
|
18912
|
+
payment_method_id: paymentMethod,
|
|
18913
|
+
rank: 1
|
|
18914
|
+
}
|
|
18915
|
+
],
|
|
18916
|
+
schedule: {
|
|
18917
|
+
reference_id: new ObjectId20().toString(),
|
|
18918
|
+
interval,
|
|
18919
|
+
interval_count: 1,
|
|
18920
|
+
anchor_date: "2022-02-15T09:44:19.546Z",
|
|
18921
|
+
retry_interval: "DAY",
|
|
18922
|
+
retry_interval_count: 1,
|
|
18923
|
+
total_retry: 3,
|
|
18924
|
+
failed_attempt_notifications: [1, 3]
|
|
18925
|
+
},
|
|
18926
|
+
notification_config: {
|
|
18927
|
+
locale: "en",
|
|
18928
|
+
recurring_created: ["WHATSAPP", "EMAIL"],
|
|
18929
|
+
recurring_succeeded: ["WHATSAPP", "EMAIL"],
|
|
18930
|
+
recurring_failed: ["WHATSAPP", "EMAIL"]
|
|
18931
|
+
},
|
|
18932
|
+
failed_cycle_action: "STOP",
|
|
18933
|
+
immediate_action_type: "FULL_AMOUNT",
|
|
18934
|
+
metadata: null,
|
|
18935
|
+
description
|
|
18936
|
+
});
|
|
18937
|
+
return res.data;
|
|
18938
|
+
} catch (error) {
|
|
18939
|
+
console.log(error);
|
|
18940
|
+
throw new BadRequestError23("Failed to create subscription.");
|
|
18941
|
+
}
|
|
18942
|
+
}
|
|
18943
|
+
async function checkSubscriptionStatus(subscriptionId) {
|
|
18944
|
+
try {
|
|
18945
|
+
const res = await axios2.get(`/recurring/plans/${subscriptionId}`);
|
|
18946
|
+
return res.data.status;
|
|
18717
18947
|
} catch (error) {
|
|
18718
|
-
throw new
|
|
18948
|
+
throw new BadRequestError23("Failed to get subscription status.");
|
|
18719
18949
|
}
|
|
18720
18950
|
}
|
|
18721
18951
|
async function cancelSubscription(subscriptionId) {
|
|
18722
18952
|
try {
|
|
18723
|
-
const
|
|
18724
|
-
|
|
18725
|
-
const response = await axios_default.post(
|
|
18726
|
-
`${PAYPAL_API_URL}/v1/billing/subscriptions/${subscriptionId}/cancel`,
|
|
18727
|
-
{},
|
|
18728
|
-
{
|
|
18729
|
-
headers: {
|
|
18730
|
-
Authorization: `Bearer ${accessToken}`,
|
|
18731
|
-
"Content-Type": "application/json"
|
|
18732
|
-
}
|
|
18733
|
-
}
|
|
18953
|
+
const res = await axios2.get(
|
|
18954
|
+
`/recurring/plans/${subscriptionId}/deactivate`
|
|
18734
18955
|
);
|
|
18735
|
-
|
|
18736
|
-
return { message: "Subscription canceled successfully." };
|
|
18737
|
-
} else {
|
|
18738
|
-
throw new BadRequestError22("Failed to cancel subscription.");
|
|
18739
|
-
}
|
|
18956
|
+
return res.data.status;
|
|
18740
18957
|
} catch (error) {
|
|
18741
|
-
throw new
|
|
18958
|
+
throw new BadRequestError23("Failed to get subscription status.");
|
|
18742
18959
|
}
|
|
18743
18960
|
}
|
|
18744
18961
|
return {
|
|
18745
|
-
|
|
18746
|
-
|
|
18962
|
+
createCustomer,
|
|
18963
|
+
linkPaymentMethodEWallet,
|
|
18964
|
+
initGCashLinkingAndPaymentRequest,
|
|
18965
|
+
initSubscription,
|
|
18966
|
+
linkPaymentMethodCard,
|
|
18967
|
+
eWalletSubsequentPayment,
|
|
18968
|
+
checkSubscriptionStatus,
|
|
18747
18969
|
cancelSubscription
|
|
18748
18970
|
};
|
|
18749
18971
|
}
|
|
18750
18972
|
|
|
18751
|
-
// src/
|
|
18752
|
-
import
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
|
|
18764
|
-
user: Joi10.string().required(),
|
|
18765
|
-
subscriptionId: Joi10.string().required()
|
|
18766
|
-
});
|
|
18767
|
-
const { error } = validation.validate(value);
|
|
18768
|
-
if (error) {
|
|
18769
|
-
next(new BadRequestError23(error.message));
|
|
18770
|
-
}
|
|
18973
|
+
// src/repositories/payment-method.repository.ts
|
|
18974
|
+
import {
|
|
18975
|
+
BadRequestError as BadRequestError25,
|
|
18976
|
+
InternalServerError as InternalServerError18,
|
|
18977
|
+
logger as logger11,
|
|
18978
|
+
useAtlas as useAtlas15
|
|
18979
|
+
} from "@goweekdays/utils";
|
|
18980
|
+
|
|
18981
|
+
// src/models/payment-method.model.ts
|
|
18982
|
+
import { BadRequestError as BadRequestError24 } from "@goweekdays/utils";
|
|
18983
|
+
import { ObjectId as ObjectId21 } from "mongodb";
|
|
18984
|
+
function MPaymentMethod(value) {
|
|
18985
|
+
if (value.user) {
|
|
18771
18986
|
try {
|
|
18772
|
-
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
return;
|
|
18776
|
-
} catch (error2) {
|
|
18777
|
-
next(error2);
|
|
18987
|
+
value.user = new ObjectId21(value.user);
|
|
18988
|
+
} catch (error) {
|
|
18989
|
+
throw new BadRequestError24("Invalid user ID.");
|
|
18778
18990
|
}
|
|
18779
18991
|
}
|
|
18780
|
-
|
|
18781
|
-
const id = req.params.id;
|
|
18782
|
-
const validation = Joi10.string().required();
|
|
18783
|
-
const { error } = validation.validate(id);
|
|
18784
|
-
if (error) {
|
|
18785
|
-
next(new BadRequestError23(error.message));
|
|
18786
|
-
}
|
|
18992
|
+
if (value.org) {
|
|
18787
18993
|
try {
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
} catch (error2) {
|
|
18792
|
-
next(error2);
|
|
18994
|
+
value.org = new ObjectId21(value.org);
|
|
18995
|
+
} catch (error) {
|
|
18996
|
+
throw new BadRequestError24("Invalid org ID.");
|
|
18793
18997
|
}
|
|
18794
18998
|
}
|
|
18795
|
-
|
|
18796
|
-
|
|
18797
|
-
|
|
18798
|
-
|
|
18799
|
-
|
|
18800
|
-
|
|
18801
|
-
|
|
18802
|
-
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
18806
|
-
|
|
18807
|
-
|
|
18999
|
+
return {
|
|
19000
|
+
_id: value._id ?? new ObjectId21(),
|
|
19001
|
+
user: value.user ?? "",
|
|
19002
|
+
org: value.org ?? "",
|
|
19003
|
+
name: value.name,
|
|
19004
|
+
description: value.description,
|
|
19005
|
+
type: value.type,
|
|
19006
|
+
paymentId: value.paymentId ?? "",
|
|
19007
|
+
customerId: value.customerId ?? "",
|
|
19008
|
+
number: value.number,
|
|
19009
|
+
expiry: value.expiry ?? "",
|
|
19010
|
+
cvv: value.cvv ?? "",
|
|
19011
|
+
status: value.status ?? "active",
|
|
19012
|
+
createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
19013
|
+
deletedAt: value.deletedAt ?? ""
|
|
19014
|
+
};
|
|
19015
|
+
}
|
|
19016
|
+
|
|
19017
|
+
// src/repositories/payment-method.repository.ts
|
|
19018
|
+
import { ObjectId as ObjectId22 } from "mongodb";
|
|
19019
|
+
function usePaymentMethodRepo() {
|
|
19020
|
+
const db = useAtlas15.getDb();
|
|
19021
|
+
if (!db) {
|
|
19022
|
+
throw new BadRequestError25("Unable to connect to server.");
|
|
19023
|
+
}
|
|
19024
|
+
const collection = db.collection("payment-methods");
|
|
19025
|
+
async function createIndex() {
|
|
18808
19026
|
try {
|
|
18809
|
-
|
|
18810
|
-
|
|
18811
|
-
|
|
18812
|
-
} catch (error2) {
|
|
18813
|
-
next(error2);
|
|
19027
|
+
await collection.createIndex([{ user: 1 }]);
|
|
19028
|
+
} catch (error) {
|
|
19029
|
+
throw new BadRequestError25("Failed to create index on payment method.");
|
|
18814
19030
|
}
|
|
18815
19031
|
}
|
|
18816
|
-
async function
|
|
18817
|
-
const id = req.params.id;
|
|
18818
|
-
const validation = Joi10.string().required();
|
|
18819
|
-
const { error } = validation.validate(id);
|
|
18820
|
-
if (error) {
|
|
18821
|
-
next(new BadRequestError23(error.message));
|
|
18822
|
-
}
|
|
19032
|
+
async function createUniqueIndex() {
|
|
18823
19033
|
try {
|
|
18824
|
-
|
|
18825
|
-
|
|
18826
|
-
|
|
18827
|
-
|
|
18828
|
-
|
|
19034
|
+
await collection.createIndex(
|
|
19035
|
+
{
|
|
19036
|
+
user: 1,
|
|
19037
|
+
org: 1,
|
|
19038
|
+
name: 1,
|
|
19039
|
+
paymentId: 1,
|
|
19040
|
+
number: 1
|
|
19041
|
+
},
|
|
19042
|
+
{ unique: true }
|
|
19043
|
+
);
|
|
19044
|
+
} catch (error) {
|
|
19045
|
+
throw new BadRequestError25(
|
|
19046
|
+
"Failed to create unique index on payment method."
|
|
19047
|
+
);
|
|
18829
19048
|
}
|
|
18830
19049
|
}
|
|
18831
|
-
async function
|
|
18832
|
-
const id = req.params.id;
|
|
18833
|
-
const validation = Joi10.string().required();
|
|
18834
|
-
const { error } = validation.validate(id);
|
|
18835
|
-
if (error) {
|
|
18836
|
-
next(new BadRequestError23(error.message));
|
|
18837
|
-
}
|
|
19050
|
+
async function add(value, session) {
|
|
18838
19051
|
try {
|
|
18839
|
-
|
|
18840
|
-
|
|
18841
|
-
return;
|
|
18842
|
-
} catch (
|
|
18843
|
-
|
|
19052
|
+
value = MPaymentMethod(value);
|
|
19053
|
+
await collection.insertOne(value, { session });
|
|
19054
|
+
return "Successfully added payment method.";
|
|
19055
|
+
} catch (error) {
|
|
19056
|
+
logger11.log({ level: "error", message: `${error}` });
|
|
19057
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
19058
|
+
if (isDuplicated) {
|
|
19059
|
+
throw new BadRequestError25("Payment method already exist.");
|
|
19060
|
+
}
|
|
19061
|
+
throw new InternalServerError18("Failed to add payment method.");
|
|
18844
19062
|
}
|
|
18845
19063
|
}
|
|
18846
|
-
|
|
18847
|
-
|
|
18848
|
-
|
|
18849
|
-
|
|
18850
|
-
|
|
18851
|
-
|
|
19064
|
+
function getByUser(user) {
|
|
19065
|
+
try {
|
|
19066
|
+
user = new ObjectId22(user);
|
|
19067
|
+
} catch (error) {
|
|
19068
|
+
throw new BadRequestError25("Invalid user ID.");
|
|
19069
|
+
}
|
|
19070
|
+
try {
|
|
19071
|
+
return collection.aggregate([
|
|
19072
|
+
{ $match: { user } },
|
|
19073
|
+
{ $sort: { createdAt: -1 } },
|
|
19074
|
+
{
|
|
19075
|
+
$project: {
|
|
19076
|
+
_id: 1,
|
|
19077
|
+
name: 1,
|
|
19078
|
+
type: 1,
|
|
19079
|
+
number: 1,
|
|
19080
|
+
paymentId: 1,
|
|
19081
|
+
customerId: 1,
|
|
19082
|
+
status: 1
|
|
19083
|
+
}
|
|
19084
|
+
}
|
|
19085
|
+
]).toArray();
|
|
19086
|
+
} catch (error) {
|
|
19087
|
+
throw new BadRequestError25("Failed to get payment methods.");
|
|
19088
|
+
}
|
|
19089
|
+
}
|
|
19090
|
+
async function getByPaymentMethodId(paymentId) {
|
|
19091
|
+
if (!paymentId) {
|
|
19092
|
+
throw new BadRequestError25("Invalid payment method ID.");
|
|
19093
|
+
}
|
|
19094
|
+
try {
|
|
19095
|
+
return await collection.findOne({ paymentId });
|
|
19096
|
+
} catch (error) {
|
|
19097
|
+
throw new BadRequestError25("Failed to retrieve payment method.");
|
|
19098
|
+
}
|
|
19099
|
+
}
|
|
19100
|
+
async function deleteById(_id) {
|
|
19101
|
+
try {
|
|
19102
|
+
_id = new ObjectId22(_id);
|
|
19103
|
+
} catch (error) {
|
|
19104
|
+
throw new BadRequestError25("Invalid payment method ID.");
|
|
19105
|
+
}
|
|
19106
|
+
try {
|
|
19107
|
+
await collection.updateOne(
|
|
19108
|
+
{ _id },
|
|
19109
|
+
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
19110
|
+
);
|
|
19111
|
+
return "Successfully deleted payment method.";
|
|
19112
|
+
} catch (error) {
|
|
19113
|
+
throw new BadRequestError25("Failed to delete payment method.");
|
|
19114
|
+
}
|
|
19115
|
+
}
|
|
19116
|
+
return {
|
|
19117
|
+
createIndex,
|
|
19118
|
+
add,
|
|
19119
|
+
getByUser,
|
|
19120
|
+
deleteById,
|
|
19121
|
+
createUniqueIndex,
|
|
19122
|
+
getByPaymentMethodId
|
|
19123
|
+
};
|
|
19124
|
+
}
|
|
19125
|
+
|
|
19126
|
+
// src/repositories/organization.repository.ts
|
|
19127
|
+
import {
|
|
19128
|
+
AppError as AppError6,
|
|
19129
|
+
BadRequestError as BadRequestError27,
|
|
19130
|
+
InternalServerError as InternalServerError19,
|
|
19131
|
+
logger as logger12,
|
|
19132
|
+
paginate as paginate9,
|
|
19133
|
+
useAtlas as useAtlas16
|
|
19134
|
+
} from "@goweekdays/utils";
|
|
19135
|
+
|
|
19136
|
+
// src/models/organization.model.ts
|
|
19137
|
+
import { BadRequestError as BadRequestError26 } from "@goweekdays/utils";
|
|
19138
|
+
import Joi10 from "joi";
|
|
19139
|
+
import { ObjectId as ObjectId23 } from "mongodb";
|
|
19140
|
+
function MOrg(value) {
|
|
19141
|
+
const schema = Joi10.object({
|
|
19142
|
+
_id: Joi10.string().hex().optional().allow("", null),
|
|
19143
|
+
name: Joi10.string().required(),
|
|
19144
|
+
email: Joi10.string().email().required(),
|
|
19145
|
+
contact: Joi10.string().required(),
|
|
19146
|
+
type: Joi10.string().required(),
|
|
19147
|
+
busInst: Joi10.string().optional().allow("", null),
|
|
19148
|
+
description: Joi10.string().optional().allow("", null),
|
|
19149
|
+
status: Joi10.string().optional().allow("", null),
|
|
19150
|
+
createdAt: Joi10.string().optional().allow("", null),
|
|
19151
|
+
updatedAt: Joi10.string().optional().allow("", null),
|
|
19152
|
+
deletedAt: Joi10.string().optional().allow("", null)
|
|
19153
|
+
});
|
|
19154
|
+
const { error } = schema.validate(value);
|
|
19155
|
+
if (error) {
|
|
19156
|
+
throw new BadRequestError26(error.message);
|
|
19157
|
+
}
|
|
19158
|
+
if (value._id) {
|
|
19159
|
+
try {
|
|
19160
|
+
value._id = new ObjectId23(value._id);
|
|
19161
|
+
} catch (error2) {
|
|
19162
|
+
throw new BadRequestError26("Invalid ID.");
|
|
19163
|
+
}
|
|
19164
|
+
}
|
|
19165
|
+
return {
|
|
19166
|
+
_id: value._id,
|
|
19167
|
+
name: value.name,
|
|
19168
|
+
description: value.description,
|
|
19169
|
+
type: value.type,
|
|
19170
|
+
email: value.email,
|
|
19171
|
+
contact: value.contact,
|
|
19172
|
+
status: value.status || "active",
|
|
19173
|
+
createdAt: value.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
19174
|
+
updatedAt: "",
|
|
19175
|
+
deletedAt: ""
|
|
19176
|
+
};
|
|
19177
|
+
}
|
|
19178
|
+
|
|
19179
|
+
// src/repositories/organization.repository.ts
|
|
19180
|
+
import { ObjectId as ObjectId24 } from "mongodb";
|
|
19181
|
+
function useOrgRepo() {
|
|
19182
|
+
const db = useAtlas16.getDb();
|
|
19183
|
+
if (!db) {
|
|
19184
|
+
throw new Error("Unable to connect to server.");
|
|
19185
|
+
}
|
|
19186
|
+
const collection = db.collection("organizations");
|
|
19187
|
+
async function createIndex() {
|
|
19188
|
+
try {
|
|
19189
|
+
await collection.createIndex([
|
|
19190
|
+
{ name: 1 },
|
|
19191
|
+
{ description: 1 },
|
|
19192
|
+
{ status: 1 }
|
|
19193
|
+
]);
|
|
19194
|
+
} catch (error) {
|
|
19195
|
+
throw new Error("Failed to create index.");
|
|
19196
|
+
}
|
|
19197
|
+
}
|
|
19198
|
+
async function createTextIndex() {
|
|
19199
|
+
try {
|
|
19200
|
+
await collection.createIndex({
|
|
19201
|
+
name: "text",
|
|
19202
|
+
description: "text"
|
|
19203
|
+
});
|
|
19204
|
+
} catch (error) {
|
|
19205
|
+
throw new Error("Failed to create text index on name and description.");
|
|
19206
|
+
}
|
|
19207
|
+
}
|
|
19208
|
+
async function createUniqueIndex() {
|
|
19209
|
+
try {
|
|
19210
|
+
await collection.createIndex(
|
|
19211
|
+
{
|
|
19212
|
+
name: 1
|
|
19213
|
+
},
|
|
19214
|
+
{ unique: true }
|
|
19215
|
+
);
|
|
19216
|
+
} catch (error) {
|
|
19217
|
+
throw new Error("Failed to create unique index on name.");
|
|
19218
|
+
}
|
|
19219
|
+
}
|
|
19220
|
+
async function add(value, session) {
|
|
19221
|
+
try {
|
|
19222
|
+
value = MOrg(value);
|
|
19223
|
+
const res = await collection.insertOne(value, session);
|
|
19224
|
+
return res.insertedId;
|
|
19225
|
+
} catch (error) {
|
|
19226
|
+
logger12.log({
|
|
19227
|
+
level: "error",
|
|
19228
|
+
message: error.message
|
|
19229
|
+
});
|
|
19230
|
+
if (error instanceof AppError6) {
|
|
19231
|
+
throw error;
|
|
19232
|
+
} else {
|
|
19233
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
19234
|
+
if (isDuplicated) {
|
|
19235
|
+
throw new BadRequestError27("Organization already exist.");
|
|
19236
|
+
}
|
|
19237
|
+
throw new Error("Failed to create organization.");
|
|
19238
|
+
}
|
|
19239
|
+
}
|
|
19240
|
+
}
|
|
19241
|
+
async function getOrgs({
|
|
19242
|
+
search = "",
|
|
19243
|
+
page = 1,
|
|
19244
|
+
limit = 10,
|
|
19245
|
+
sort = {},
|
|
19246
|
+
status = "active"
|
|
19247
|
+
} = {}) {
|
|
19248
|
+
page = page > 0 ? page - 1 : 0;
|
|
19249
|
+
const query = { status };
|
|
19250
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
19251
|
+
if (search) {
|
|
19252
|
+
query.$text = { $search: search };
|
|
19253
|
+
}
|
|
19254
|
+
try {
|
|
19255
|
+
const items = await collection.aggregate([
|
|
19256
|
+
{ $match: query },
|
|
19257
|
+
{ $sort: sort },
|
|
19258
|
+
{ $skip: page * limit },
|
|
19259
|
+
{ $limit: limit },
|
|
19260
|
+
{
|
|
19261
|
+
$project: {
|
|
19262
|
+
_id: 1,
|
|
19263
|
+
name: 1,
|
|
19264
|
+
description: 1,
|
|
19265
|
+
status: 1,
|
|
19266
|
+
createdAt: 1
|
|
19267
|
+
}
|
|
19268
|
+
}
|
|
19269
|
+
]).toArray();
|
|
19270
|
+
const length = await collection.countDocuments(query);
|
|
19271
|
+
return paginate9(items, page, limit, length);
|
|
19272
|
+
} catch (error) {
|
|
19273
|
+
logger12.log({ level: "error", message: `${error}` });
|
|
19274
|
+
throw error;
|
|
19275
|
+
}
|
|
19276
|
+
}
|
|
19277
|
+
async function getById(_id) {
|
|
19278
|
+
try {
|
|
19279
|
+
_id = new ObjectId24(_id);
|
|
19280
|
+
} catch (error) {
|
|
19281
|
+
throw new BadRequestError27("Invalid ID.");
|
|
19282
|
+
}
|
|
19283
|
+
try {
|
|
19284
|
+
const result = await collection.findOne({ _id });
|
|
19285
|
+
if (!result) {
|
|
19286
|
+
throw new BadRequestError27("Organization not found.");
|
|
19287
|
+
}
|
|
19288
|
+
return result;
|
|
19289
|
+
} catch (error) {
|
|
19290
|
+
if (error instanceof AppError6) {
|
|
19291
|
+
throw error;
|
|
19292
|
+
} else {
|
|
19293
|
+
throw new InternalServerError19("Failed to get organization.");
|
|
19294
|
+
}
|
|
19295
|
+
}
|
|
19296
|
+
}
|
|
19297
|
+
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
19298
|
+
const allowedFields = ["name", "description"];
|
|
19299
|
+
if (!allowedFields.includes(field)) {
|
|
19300
|
+
throw new BadRequestError27(
|
|
19301
|
+
`Field "${field}" is not allowed to be updated.`
|
|
19302
|
+
);
|
|
19303
|
+
}
|
|
19304
|
+
try {
|
|
19305
|
+
_id = new ObjectId24(_id);
|
|
19306
|
+
} catch (error) {
|
|
19307
|
+
throw new BadRequestError27("Invalid ID.");
|
|
19308
|
+
}
|
|
19309
|
+
try {
|
|
19310
|
+
await collection.updateOne(
|
|
19311
|
+
{ _id },
|
|
19312
|
+
{ $set: { [field]: value } },
|
|
19313
|
+
// Dynamically set the field
|
|
19314
|
+
{ session }
|
|
19315
|
+
);
|
|
19316
|
+
return `Successfully updated user ${field}.`;
|
|
19317
|
+
} catch (error) {
|
|
19318
|
+
throw new InternalServerError19(`Failed to update organization ${field}.`);
|
|
19319
|
+
}
|
|
19320
|
+
}
|
|
19321
|
+
async function deleteById(_id) {
|
|
19322
|
+
try {
|
|
19323
|
+
_id = new ObjectId24(_id);
|
|
19324
|
+
} catch (error) {
|
|
19325
|
+
throw new BadRequestError27("Invalid ID.");
|
|
19326
|
+
}
|
|
19327
|
+
try {
|
|
19328
|
+
await collection.updateOne(
|
|
19329
|
+
{ _id },
|
|
19330
|
+
{ $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
|
|
19331
|
+
);
|
|
19332
|
+
return "Successfully deleted organization.";
|
|
19333
|
+
} catch (error) {
|
|
19334
|
+
throw new InternalServerError19("Failed to delete organization.");
|
|
19335
|
+
}
|
|
19336
|
+
}
|
|
19337
|
+
return {
|
|
19338
|
+
createIndex,
|
|
19339
|
+
createTextIndex,
|
|
19340
|
+
createUniqueIndex,
|
|
19341
|
+
add,
|
|
19342
|
+
getOrgs,
|
|
19343
|
+
getById,
|
|
19344
|
+
updateFieldById,
|
|
19345
|
+
deleteById
|
|
19346
|
+
};
|
|
19347
|
+
}
|
|
19348
|
+
|
|
19349
|
+
// src/repositories/address.repository.ts
|
|
19350
|
+
import { BadRequestError as BadRequestError29, useAtlas as useAtlas17 } from "@goweekdays/utils";
|
|
19351
|
+
|
|
19352
|
+
// src/models/address.model.ts
|
|
19353
|
+
import { BadRequestError as BadRequestError28 } from "@goweekdays/utils";
|
|
19354
|
+
import { ObjectId as ObjectId25 } from "mongodb";
|
|
19355
|
+
function MAddress(value) {
|
|
19356
|
+
if (value.user) {
|
|
19357
|
+
try {
|
|
19358
|
+
value.user = new ObjectId25(value.user);
|
|
19359
|
+
} catch (error) {
|
|
19360
|
+
throw new BadRequestError28("Invalid user ID.");
|
|
19361
|
+
}
|
|
19362
|
+
}
|
|
19363
|
+
if (value.org) {
|
|
19364
|
+
try {
|
|
19365
|
+
value.org = new ObjectId25(value.org);
|
|
19366
|
+
} catch (error) {
|
|
19367
|
+
throw new BadRequestError28("Invalid org ID.");
|
|
19368
|
+
}
|
|
19369
|
+
}
|
|
19370
|
+
return {
|
|
19371
|
+
type: value.type ?? "billing",
|
|
19372
|
+
user: value.user ?? "",
|
|
19373
|
+
org: value.org ?? "",
|
|
19374
|
+
country: value.country ?? "",
|
|
19375
|
+
address: value.address ?? "",
|
|
19376
|
+
continuedAddress: value.continuedAddress ?? "",
|
|
19377
|
+
city: value.city ?? "",
|
|
19378
|
+
province: value.province ?? "",
|
|
19379
|
+
postalCode: value.postalCode ?? "",
|
|
19380
|
+
taxId: value.taxId ?? ""
|
|
19381
|
+
};
|
|
19382
|
+
}
|
|
19383
|
+
|
|
19384
|
+
// src/repositories/address.repository.ts
|
|
19385
|
+
import { ObjectId as ObjectId26 } from "mongodb";
|
|
19386
|
+
function useAddressRepo() {
|
|
19387
|
+
const db = useAtlas17.getDb();
|
|
19388
|
+
if (!db) {
|
|
19389
|
+
throw new BadRequestError29("Unable to connect to server.");
|
|
19390
|
+
}
|
|
19391
|
+
const collection = db.collection("addresses");
|
|
19392
|
+
async function createIndex() {
|
|
19393
|
+
try {
|
|
19394
|
+
await collection.createIndex([{ user: 1 }, { type: 1 }]);
|
|
19395
|
+
} catch (error) {
|
|
19396
|
+
throw new BadRequestError29("Failed to create index on address.");
|
|
19397
|
+
}
|
|
19398
|
+
}
|
|
19399
|
+
async function add(value, session) {
|
|
19400
|
+
try {
|
|
19401
|
+
value = MAddress(value);
|
|
19402
|
+
const res = await collection.insertOne(value, { session });
|
|
19403
|
+
return res.insertedId;
|
|
19404
|
+
} catch (error) {
|
|
19405
|
+
throw new BadRequestError29("Failed to create address.");
|
|
19406
|
+
}
|
|
19407
|
+
}
|
|
19408
|
+
async function getByUserId(user) {
|
|
19409
|
+
try {
|
|
19410
|
+
user = new ObjectId26(user);
|
|
19411
|
+
} catch (error) {
|
|
19412
|
+
throw new BadRequestError29("Invalid user ID.");
|
|
19413
|
+
}
|
|
19414
|
+
try {
|
|
19415
|
+
return await collection.findOne({ user });
|
|
19416
|
+
} catch (error) {
|
|
19417
|
+
throw new BadRequestError29("Failed to get address by ID.");
|
|
19418
|
+
}
|
|
19419
|
+
}
|
|
19420
|
+
return {
|
|
19421
|
+
createIndex,
|
|
19422
|
+
add,
|
|
19423
|
+
getByUserId
|
|
19424
|
+
};
|
|
19425
|
+
}
|
|
19426
|
+
|
|
19427
|
+
// src/services/subscription.service.ts
|
|
19428
|
+
function useSubscriptionService() {
|
|
19429
|
+
const { getByUserId: _getByUserId, add } = useSubscriptionRepo();
|
|
19430
|
+
const { getUserById: _getUserByUserId } = useUserRepo();
|
|
19431
|
+
const { initSubscription, checkSubscriptionStatus, cancelSubscription } = useXenditService();
|
|
19432
|
+
const { add: addPaymentMethod, getByPaymentMethodId } = usePaymentMethodRepo();
|
|
19433
|
+
const { add: addOrg } = useOrgRepo();
|
|
19434
|
+
const { add: addAddress } = useAddressRepo();
|
|
19435
|
+
async function createOrgSubscription(value) {
|
|
19436
|
+
const session = useAtlas18.getClient()?.startSession();
|
|
19437
|
+
session?.startTransaction();
|
|
19438
|
+
try {
|
|
19439
|
+
const _user = await _getUserByUserId(value.user);
|
|
19440
|
+
if (!_user) {
|
|
19441
|
+
throw new BadRequestError30("User not found.");
|
|
19442
|
+
}
|
|
19443
|
+
const payment = await getByPaymentMethodId(value.payment_method_id);
|
|
19444
|
+
if (!payment) {
|
|
19445
|
+
throw new BadRequestError30("Payment method not found.");
|
|
19446
|
+
}
|
|
19447
|
+
const org = await addOrg(value.organization, session);
|
|
19448
|
+
payment.user = "";
|
|
19449
|
+
payment.org = org;
|
|
19450
|
+
delete payment._id;
|
|
19451
|
+
console.log(payment);
|
|
19452
|
+
await addPaymentMethod(payment, session);
|
|
19453
|
+
value.billingAddress.org = org;
|
|
19454
|
+
await addAddress(value.billingAddress, session);
|
|
19455
|
+
const subscription = await initSubscription({
|
|
19456
|
+
customer: value.customer_id,
|
|
19457
|
+
paymentMethod: value.payment_method_id,
|
|
19458
|
+
amount: value.amount,
|
|
19459
|
+
description: "GoWeekdays Organization Monthly Subscription."
|
|
19460
|
+
});
|
|
19461
|
+
await add(
|
|
19462
|
+
{
|
|
19463
|
+
org,
|
|
19464
|
+
subscriptionId: subscription.id
|
|
19465
|
+
},
|
|
19466
|
+
session
|
|
19467
|
+
);
|
|
19468
|
+
await session?.commitTransaction();
|
|
19469
|
+
return "Subscription created successfully.";
|
|
19470
|
+
} catch (error) {
|
|
19471
|
+
await session?.abortTransaction();
|
|
19472
|
+
throw error;
|
|
19473
|
+
} finally {
|
|
19474
|
+
session?.endSession();
|
|
19475
|
+
}
|
|
19476
|
+
}
|
|
19477
|
+
async function createAffiliateSubscription({
|
|
19478
|
+
user = "",
|
|
19479
|
+
amount = 0,
|
|
19480
|
+
payment_method_id = "",
|
|
19481
|
+
customer_id = ""
|
|
19482
|
+
} = {}) {
|
|
19483
|
+
const session = useAtlas18.getClient()?.startSession();
|
|
19484
|
+
session?.startTransaction();
|
|
19485
|
+
try {
|
|
19486
|
+
const _user = await _getUserByUserId(user);
|
|
19487
|
+
if (!_user) {
|
|
19488
|
+
throw new BadRequestError30("User not found.");
|
|
19489
|
+
}
|
|
19490
|
+
const subscription = await initSubscription({
|
|
19491
|
+
customer: customer_id,
|
|
19492
|
+
paymentMethod: payment_method_id,
|
|
19493
|
+
amount,
|
|
19494
|
+
description: "GoWeekdays Affiliate Annual Subscription.",
|
|
19495
|
+
interval: "YEAR"
|
|
19496
|
+
});
|
|
19497
|
+
await add(
|
|
19498
|
+
{
|
|
19499
|
+
user,
|
|
19500
|
+
subscriptionId: subscription.id
|
|
19501
|
+
},
|
|
19502
|
+
session
|
|
19503
|
+
);
|
|
19504
|
+
await session?.commitTransaction();
|
|
19505
|
+
return "Subscription created successfully.";
|
|
19506
|
+
} catch (error) {
|
|
19507
|
+
await session?.abortTransaction();
|
|
19508
|
+
throw error;
|
|
19509
|
+
} finally {
|
|
19510
|
+
session?.endSession();
|
|
19511
|
+
}
|
|
19512
|
+
}
|
|
19513
|
+
async function getByUserId(id) {
|
|
19514
|
+
try {
|
|
19515
|
+
const subscription = await _getByUserId(id);
|
|
19516
|
+
if (!subscription) {
|
|
19517
|
+
throw new BadRequestError30("Subscription not found.");
|
|
19518
|
+
}
|
|
19519
|
+
return subscription;
|
|
19520
|
+
} catch (error) {
|
|
19521
|
+
throw error;
|
|
19522
|
+
}
|
|
19523
|
+
}
|
|
19524
|
+
async function getStatusByUser(user) {
|
|
19525
|
+
try {
|
|
19526
|
+
const userSubscription = await getByUserId(user);
|
|
19527
|
+
const status = await checkSubscriptionStatus(
|
|
19528
|
+
userSubscription.subscriptionId
|
|
19529
|
+
);
|
|
19530
|
+
return status;
|
|
19531
|
+
} catch (error) {
|
|
19532
|
+
throw new BadRequestError30("Failed to fetch subscription status");
|
|
19533
|
+
}
|
|
19534
|
+
}
|
|
19535
|
+
return {
|
|
19536
|
+
getByUserId,
|
|
19537
|
+
getStatusByUser,
|
|
19538
|
+
createAffiliateSubscription,
|
|
19539
|
+
createOrgSubscription
|
|
19540
|
+
};
|
|
19541
|
+
}
|
|
19542
|
+
|
|
19543
|
+
// src/controllers/subscription.controller.ts
|
|
19544
|
+
import Joi11 from "joi";
|
|
19545
|
+
import { BadRequestError as BadRequestError31 } from "@goweekdays/utils";
|
|
19546
|
+
function useSubscriptionController() {
|
|
19547
|
+
const { add: _add, getSubscriptions: _getSubscriptions } = useSubscriptionRepo();
|
|
19548
|
+
const {
|
|
19549
|
+
getByUserId: _getByUserId,
|
|
19550
|
+
getStatusByUser: _getStatusByUser,
|
|
19551
|
+
createAffiliateSubscription: _createAffiliateSubscription,
|
|
19552
|
+
createOrgSubscription: _createOrgSubscription
|
|
19553
|
+
} = useSubscriptionService();
|
|
19554
|
+
async function add(req, res, next) {
|
|
19555
|
+
const value = req.body;
|
|
19556
|
+
const validation = Joi11.object({
|
|
19557
|
+
user: Joi11.string().required(),
|
|
19558
|
+
subscriptionId: Joi11.string().required()
|
|
19559
|
+
});
|
|
19560
|
+
const { error } = validation.validate(value);
|
|
19561
|
+
if (error) {
|
|
19562
|
+
next(new BadRequestError31(error.message));
|
|
19563
|
+
}
|
|
19564
|
+
try {
|
|
19565
|
+
const value2 = req.body;
|
|
19566
|
+
const id = await _add(value2);
|
|
19567
|
+
res.json({ message: "Successfully added subscription.", id });
|
|
19568
|
+
return;
|
|
19569
|
+
} catch (error2) {
|
|
19570
|
+
next(error2);
|
|
19571
|
+
}
|
|
19572
|
+
}
|
|
19573
|
+
async function getByUserId(req, res, next) {
|
|
19574
|
+
const id = req.params.id;
|
|
19575
|
+
const validation = Joi11.string().required();
|
|
19576
|
+
const { error } = validation.validate(id);
|
|
19577
|
+
if (error) {
|
|
19578
|
+
next(new BadRequestError31(error.message));
|
|
19579
|
+
}
|
|
19580
|
+
try {
|
|
19581
|
+
const subscription = await _getByUserId(id);
|
|
19582
|
+
res.json(subscription);
|
|
19583
|
+
return;
|
|
19584
|
+
} catch (error2) {
|
|
19585
|
+
next(error2);
|
|
19586
|
+
}
|
|
19587
|
+
}
|
|
19588
|
+
async function getSubscriptions(req, res, next) {
|
|
19589
|
+
const status = req.query.status ?? "";
|
|
19590
|
+
const search = req.query.search ?? "";
|
|
19591
|
+
const page = Number(req.query.page) ?? 1;
|
|
19592
|
+
const validation = Joi11.object({
|
|
19593
|
+
status: Joi11.string().required(),
|
|
19594
|
+
search: Joi11.string().optional().allow("", null),
|
|
19595
|
+
page: Joi11.number().required()
|
|
19596
|
+
});
|
|
19597
|
+
const { error } = validation.validate({ status, search, page });
|
|
19598
|
+
if (error) {
|
|
19599
|
+
next(new BadRequestError31(error.message));
|
|
19600
|
+
}
|
|
19601
|
+
try {
|
|
19602
|
+
const subscriptions = await _getSubscriptions({ status, search, page });
|
|
19603
|
+
res.json(subscriptions);
|
|
19604
|
+
return;
|
|
19605
|
+
} catch (error2) {
|
|
19606
|
+
next(error2);
|
|
19607
|
+
}
|
|
19608
|
+
}
|
|
19609
|
+
async function getSubscriptionStatus(req, res, next) {
|
|
19610
|
+
const id = req.params.id;
|
|
19611
|
+
const validation = Joi11.string().required();
|
|
19612
|
+
const { error } = validation.validate(id);
|
|
19613
|
+
if (error) {
|
|
19614
|
+
next(new BadRequestError31(error.message));
|
|
19615
|
+
}
|
|
19616
|
+
try {
|
|
19617
|
+
const status = await _getStatusByUser(id);
|
|
19618
|
+
res.json({ status });
|
|
19619
|
+
return;
|
|
19620
|
+
} catch (error2) {
|
|
19621
|
+
next(error2);
|
|
19622
|
+
}
|
|
19623
|
+
}
|
|
19624
|
+
async function createAffiliateSubscription(req, res, next) {
|
|
19625
|
+
const amount = req.body.amount ?? 0;
|
|
19626
|
+
const payment_method_id = req.body.payment_method_id ?? "";
|
|
19627
|
+
const customer_id = req.body.customer_id ?? "";
|
|
19628
|
+
const currency = req.body.currency ?? "PHP";
|
|
19629
|
+
const user = req.headers["user"];
|
|
19630
|
+
const validation = Joi11.object({
|
|
19631
|
+
user: Joi11.string().required(),
|
|
19632
|
+
amount: Joi11.number().required(),
|
|
19633
|
+
customer_id: Joi11.string().required(),
|
|
19634
|
+
payment_method_id: Joi11.string().required(),
|
|
19635
|
+
currency: Joi11.string().optional().allow("", null)
|
|
19636
|
+
});
|
|
19637
|
+
const { error } = validation.validate({
|
|
19638
|
+
user,
|
|
19639
|
+
amount,
|
|
19640
|
+
customer_id,
|
|
19641
|
+
payment_method_id,
|
|
19642
|
+
currency
|
|
19643
|
+
});
|
|
19644
|
+
if (error) {
|
|
19645
|
+
next(new BadRequestError31(error.message));
|
|
19646
|
+
return;
|
|
19647
|
+
}
|
|
19648
|
+
try {
|
|
19649
|
+
const id = await _createAffiliateSubscription({
|
|
19650
|
+
user,
|
|
19651
|
+
amount,
|
|
19652
|
+
customer_id,
|
|
19653
|
+
payment_method_id
|
|
19654
|
+
});
|
|
19655
|
+
res.json({ message: "Successfully added subscription.", id });
|
|
19656
|
+
return;
|
|
19657
|
+
} catch (error2) {
|
|
19658
|
+
console.log(error2);
|
|
19659
|
+
next(error2);
|
|
19660
|
+
return;
|
|
19661
|
+
}
|
|
19662
|
+
}
|
|
19663
|
+
async function createOrgSubscription(req, res, next) {
|
|
19664
|
+
const value = req.body;
|
|
19665
|
+
value.user = req.headers["user"];
|
|
19666
|
+
const validation = Joi11.object({
|
|
19667
|
+
user: Joi11.string().required(),
|
|
19668
|
+
amount: Joi11.number().required(),
|
|
19669
|
+
customer_id: Joi11.string().required(),
|
|
19670
|
+
payment_method_id: Joi11.string().required(),
|
|
19671
|
+
currency: Joi11.string().optional().allow("", null),
|
|
19672
|
+
organization: Joi11.object({
|
|
19673
|
+
name: Joi11.string().required(),
|
|
19674
|
+
description: Joi11.string().optional().allow("", null),
|
|
19675
|
+
type: Joi11.string().allow("personal", "business").required(),
|
|
19676
|
+
email: Joi11.string().email().required(),
|
|
19677
|
+
contact: Joi11.string().required(),
|
|
19678
|
+
busInst: Joi11.string().optional().allow(null, "")
|
|
19679
|
+
}).required(),
|
|
19680
|
+
billingAddress: Joi11.object({
|
|
19681
|
+
type: Joi11.string().required(),
|
|
19682
|
+
country: Joi11.string().required(),
|
|
19683
|
+
address: Joi11.string().required(),
|
|
19684
|
+
continuedAddress: Joi11.string().optional().allow(null, ""),
|
|
19685
|
+
city: Joi11.string().required(),
|
|
19686
|
+
province: Joi11.string().required(),
|
|
19687
|
+
postalCode: Joi11.string().required(),
|
|
19688
|
+
taxId: Joi11.string().optional().allow(null, "")
|
|
19689
|
+
}).required()
|
|
19690
|
+
});
|
|
19691
|
+
const { error } = validation.validate(value);
|
|
19692
|
+
if (error) {
|
|
19693
|
+
next(new BadRequestError31(error.message));
|
|
19694
|
+
return;
|
|
19695
|
+
}
|
|
19696
|
+
try {
|
|
19697
|
+
const id = await _createOrgSubscription(value);
|
|
19698
|
+
res.json({ message: "Successfully added subscription.", id });
|
|
19699
|
+
return;
|
|
19700
|
+
} catch (error2) {
|
|
19701
|
+
next(error2);
|
|
19702
|
+
return;
|
|
19703
|
+
}
|
|
19704
|
+
}
|
|
19705
|
+
return {
|
|
19706
|
+
add,
|
|
19707
|
+
getByUserId,
|
|
19708
|
+
getSubscriptions,
|
|
19709
|
+
getSubscriptionStatus,
|
|
19710
|
+
createAffiliateSubscription,
|
|
19711
|
+
createOrgSubscription
|
|
19712
|
+
};
|
|
19713
|
+
}
|
|
19714
|
+
|
|
19715
|
+
// src/services/payment-method.service.ts
|
|
19716
|
+
import { BadRequestError as BadRequestError32, useAtlas as useAtlas19 } from "@goweekdays/utils";
|
|
19717
|
+
function usePaymentMethodService() {
|
|
19718
|
+
const { createCustomer, linkPaymentMethodEWallet, linkPaymentMethodCard } = useXenditService();
|
|
19719
|
+
const { getUserById } = useUserRepo();
|
|
19720
|
+
const { add } = usePaymentMethodRepo();
|
|
19721
|
+
const cardRules = {
|
|
19722
|
+
Visa: { length: 16, visibleDigits: 4 },
|
|
19723
|
+
MasterCard: { length: 16, visibleDigits: 4 },
|
|
19724
|
+
"American Express": { length: 15, visibleDigits: 5 },
|
|
19725
|
+
Discover: { length: 16, visibleDigits: 4 },
|
|
19726
|
+
"Diners Club": { length: 14, visibleDigits: 4 },
|
|
19727
|
+
JCB: { length: 16, visibleDigits: 4 },
|
|
19728
|
+
UnionPay: { length: 19, visibleDigits: 4 },
|
|
19729
|
+
Maestro: { length: 19, visibleDigits: 4 }
|
|
19730
|
+
};
|
|
19731
|
+
const detectCardType = (cardNumber) => {
|
|
19732
|
+
const patterns = {
|
|
19733
|
+
Visa: /^4/,
|
|
19734
|
+
MasterCard: /^(5[1-5]|222[1-9]|22[3-9]\d|2[3-6]\d{2}|27[01]\d|2720)/,
|
|
19735
|
+
"American Express": /^3[47]/,
|
|
19736
|
+
Discover: /^(6011|622(12[6-9]|1[3-9]\d|[2-8]\d\d|92[0-5])|64[4-9]|65)/,
|
|
19737
|
+
"Diners Club": /^3(0[0-5]|[68])/,
|
|
19738
|
+
JCB: /^35/,
|
|
19739
|
+
UnionPay: /^62/,
|
|
19740
|
+
Maestro: /^(50|5[6-9]|6\d)/
|
|
19741
|
+
};
|
|
19742
|
+
for (const [type, regex] of Object.entries(patterns)) {
|
|
19743
|
+
if (regex.test(cardNumber))
|
|
19744
|
+
return type;
|
|
19745
|
+
}
|
|
19746
|
+
return "Unknown";
|
|
19747
|
+
};
|
|
19748
|
+
const maskCardNumber = (cardNumber) => {
|
|
19749
|
+
const cardType = detectCardType(cardNumber);
|
|
19750
|
+
const rule = cardRules[cardType] || { visibleDigits: 4 };
|
|
19751
|
+
const visibleDigits = rule.visibleDigits;
|
|
19752
|
+
const maskLength = cardNumber.length - visibleDigits;
|
|
19753
|
+
if (maskLength <= 0)
|
|
19754
|
+
return cardNumber;
|
|
19755
|
+
const maskedPart = "*".repeat(maskLength);
|
|
19756
|
+
const visiblePart = cardNumber.slice(maskLength);
|
|
19757
|
+
return `${maskedPart}${visiblePart}`;
|
|
19758
|
+
};
|
|
19759
|
+
async function linkEWallet({
|
|
19760
|
+
user = "",
|
|
19761
|
+
mobile_number = "",
|
|
19762
|
+
type = "GCASH",
|
|
19763
|
+
success_return_url = "",
|
|
19764
|
+
failure_return_url = "",
|
|
19765
|
+
cancel_return_url = ""
|
|
19766
|
+
} = {}) {
|
|
19767
|
+
const session = useAtlas19.getClient()?.startSession();
|
|
19768
|
+
session?.startTransaction();
|
|
19769
|
+
try {
|
|
19770
|
+
const _user = await getUserById(user);
|
|
19771
|
+
if (!_user) {
|
|
19772
|
+
throw new BadRequestError32("User not found.");
|
|
19773
|
+
}
|
|
19774
|
+
if (!_user._id) {
|
|
19775
|
+
throw new BadRequestError32("Invalid user ID.");
|
|
19776
|
+
}
|
|
19777
|
+
const customer = await createCustomer({
|
|
19778
|
+
mobile_number,
|
|
19779
|
+
email: _user.email,
|
|
19780
|
+
given_names: _user.firstName,
|
|
19781
|
+
surname: _user.lastName
|
|
19782
|
+
});
|
|
19783
|
+
const result = await linkPaymentMethodEWallet({
|
|
19784
|
+
customerId: customer.id,
|
|
19785
|
+
type,
|
|
19786
|
+
success_return_url,
|
|
19787
|
+
failure_return_url,
|
|
19788
|
+
cancel_return_url
|
|
19789
|
+
});
|
|
19790
|
+
await add(
|
|
19791
|
+
{
|
|
19792
|
+
user: _user._id,
|
|
19793
|
+
type,
|
|
19794
|
+
status: "active",
|
|
19795
|
+
paymentId: result.id,
|
|
19796
|
+
customerId: customer.id,
|
|
19797
|
+
name: result.type,
|
|
19798
|
+
number: mobile_number
|
|
19799
|
+
},
|
|
19800
|
+
session
|
|
19801
|
+
);
|
|
19802
|
+
await session?.commitTransaction();
|
|
19803
|
+
return result;
|
|
19804
|
+
} catch (error) {
|
|
19805
|
+
console.log(error);
|
|
19806
|
+
await session?.abortTransaction();
|
|
19807
|
+
throw error;
|
|
19808
|
+
} finally {
|
|
19809
|
+
session?.endSession();
|
|
19810
|
+
}
|
|
19811
|
+
}
|
|
19812
|
+
async function linkCard({
|
|
19813
|
+
user = "",
|
|
19814
|
+
type = "",
|
|
19815
|
+
success_return_url = "",
|
|
19816
|
+
failure_return_url = "",
|
|
19817
|
+
card_number = "",
|
|
19818
|
+
expiry_month = "",
|
|
19819
|
+
expiry_year = "",
|
|
19820
|
+
cvv = "",
|
|
19821
|
+
cardholder_name = "",
|
|
19822
|
+
currency = "PHP"
|
|
19823
|
+
} = {}) {
|
|
19824
|
+
const session = useAtlas19.getClient()?.startSession();
|
|
19825
|
+
session?.startTransaction();
|
|
19826
|
+
try {
|
|
19827
|
+
const _user = await getUserById(user);
|
|
19828
|
+
if (!_user) {
|
|
19829
|
+
throw new BadRequestError32("User not found.");
|
|
19830
|
+
}
|
|
19831
|
+
if (!_user._id) {
|
|
19832
|
+
throw new BadRequestError32("Invalid user ID.");
|
|
19833
|
+
}
|
|
19834
|
+
const result = await linkPaymentMethodCard({
|
|
19835
|
+
card_number,
|
|
19836
|
+
expiry_month,
|
|
19837
|
+
expiry_year,
|
|
19838
|
+
cvv,
|
|
19839
|
+
cardholder_name,
|
|
19840
|
+
currency,
|
|
19841
|
+
success_return_url,
|
|
19842
|
+
failure_return_url
|
|
19843
|
+
});
|
|
19844
|
+
await add(
|
|
19845
|
+
{
|
|
19846
|
+
user: _user._id,
|
|
19847
|
+
type,
|
|
19848
|
+
status: "active",
|
|
19849
|
+
paymentId: result.id,
|
|
19850
|
+
name: result.type,
|
|
19851
|
+
number: maskCardNumber(card_number)
|
|
19852
|
+
},
|
|
19853
|
+
session
|
|
19854
|
+
);
|
|
19855
|
+
await session?.commitTransaction();
|
|
19856
|
+
return result;
|
|
19857
|
+
} catch (error) {
|
|
19858
|
+
console.log(error);
|
|
19859
|
+
await session?.abortTransaction();
|
|
19860
|
+
throw error;
|
|
19861
|
+
} finally {
|
|
19862
|
+
session?.endSession();
|
|
19863
|
+
}
|
|
19864
|
+
}
|
|
19865
|
+
return {
|
|
19866
|
+
linkEWallet,
|
|
19867
|
+
linkCard
|
|
19868
|
+
};
|
|
19869
|
+
}
|
|
19870
|
+
|
|
19871
|
+
// src/controllers/payment-method.controller.ts
|
|
19872
|
+
import Joi12 from "joi";
|
|
19873
|
+
import { BadRequestError as BadRequestError33 } from "@goweekdays/utils";
|
|
19874
|
+
function usePaymentMethodController() {
|
|
19875
|
+
const { linkEWallet } = usePaymentMethodService();
|
|
19876
|
+
async function linkEWalletController(req, res, next) {
|
|
19877
|
+
const mobile_number = req.body.mobile_number ?? "";
|
|
19878
|
+
const type = req.body.type ?? "";
|
|
19879
|
+
const user = req.headers["user"] ?? "";
|
|
19880
|
+
const success_return_url = req.body.success_return_url ?? "";
|
|
19881
|
+
const failure_return_url = req.body.failure_return_url ?? "";
|
|
19882
|
+
const cancel_return_url = req.body.cancel_return_url ?? "";
|
|
19883
|
+
const validation = Joi12.object({
|
|
19884
|
+
user: Joi12.string().hex().required(),
|
|
19885
|
+
mobile_number: Joi12.string().required(),
|
|
19886
|
+
type: Joi12.string().valid("GCASH", "PAYMAYA").required(),
|
|
19887
|
+
success_return_url: Joi12.string().uri().required(),
|
|
19888
|
+
failure_return_url: Joi12.string().uri().required(),
|
|
19889
|
+
cancel_return_url: Joi12.string().uri().required()
|
|
19890
|
+
});
|
|
19891
|
+
const { error } = validation.validate({
|
|
19892
|
+
user,
|
|
19893
|
+
mobile_number,
|
|
19894
|
+
type,
|
|
19895
|
+
success_return_url,
|
|
19896
|
+
failure_return_url,
|
|
19897
|
+
cancel_return_url
|
|
19898
|
+
});
|
|
19899
|
+
if (error) {
|
|
19900
|
+
next(new BadRequestError33(error.message));
|
|
19901
|
+
}
|
|
19902
|
+
try {
|
|
19903
|
+
const result = await linkEWallet({
|
|
19904
|
+
user,
|
|
19905
|
+
mobile_number,
|
|
19906
|
+
type,
|
|
19907
|
+
success_return_url,
|
|
19908
|
+
failure_return_url,
|
|
19909
|
+
cancel_return_url
|
|
19910
|
+
});
|
|
19911
|
+
res.json(result);
|
|
19912
|
+
return;
|
|
19913
|
+
} catch (error2) {
|
|
19914
|
+
next(error2);
|
|
19915
|
+
}
|
|
19916
|
+
}
|
|
19917
|
+
const { getByUser: _getByUser } = usePaymentMethodRepo();
|
|
19918
|
+
async function getByUser(req, res, next) {
|
|
19919
|
+
const user = req.headers["user"] ?? "";
|
|
19920
|
+
try {
|
|
19921
|
+
const result = await _getByUser(user);
|
|
19922
|
+
res.json(result);
|
|
19923
|
+
} catch (error) {
|
|
19924
|
+
throw error;
|
|
19925
|
+
}
|
|
19926
|
+
}
|
|
19927
|
+
return {
|
|
19928
|
+
linkEWalletController,
|
|
19929
|
+
getByUser
|
|
19930
|
+
};
|
|
19931
|
+
}
|
|
19932
|
+
|
|
19933
|
+
// src/controllers/address.controller.ts
|
|
19934
|
+
import { BadRequestError as BadRequestError34, NotFoundError as NotFoundError4 } from "@goweekdays/utils";
|
|
19935
|
+
import Joi13 from "joi";
|
|
19936
|
+
function useAddressController() {
|
|
19937
|
+
const { add: _add, getByUserId: _getByUserId } = useAddressRepo();
|
|
19938
|
+
async function add(req, res, next) {
|
|
19939
|
+
const value = req.body;
|
|
19940
|
+
const validation = Joi13.object({
|
|
19941
|
+
type: Joi13.string().required(),
|
|
19942
|
+
user: Joi13.string().hex().optional().allow("", null),
|
|
19943
|
+
org: Joi13.string().hex().optional().allow("", null),
|
|
19944
|
+
country: Joi13.string().required(),
|
|
19945
|
+
address: Joi13.string().required(),
|
|
19946
|
+
continuedAddress: Joi13.string().optional().allow("", null),
|
|
19947
|
+
city: Joi13.string().required(),
|
|
19948
|
+
province: Joi13.string().required(),
|
|
19949
|
+
postalCode: Joi13.string().required(),
|
|
19950
|
+
taxId: Joi13.string().optional().allow("", null)
|
|
19951
|
+
});
|
|
19952
|
+
const { error } = validation.validate(value);
|
|
19953
|
+
if (error) {
|
|
19954
|
+
next(new BadRequestError34(error.message));
|
|
19955
|
+
}
|
|
19956
|
+
try {
|
|
19957
|
+
const value2 = req.body;
|
|
19958
|
+
const id = await _add(value2);
|
|
19959
|
+
res.json({ message: "Successfully added subscription.", id });
|
|
19960
|
+
return;
|
|
19961
|
+
} catch (error2) {
|
|
19962
|
+
next(error2);
|
|
19963
|
+
}
|
|
19964
|
+
}
|
|
19965
|
+
async function getByUserId(req, res, next) {
|
|
19966
|
+
const user = req.params.user;
|
|
19967
|
+
const validation = Joi13.string().hex().required();
|
|
19968
|
+
const { error } = validation.validate(user);
|
|
19969
|
+
if (error) {
|
|
19970
|
+
next(new BadRequestError34(error.message));
|
|
19971
|
+
}
|
|
19972
|
+
try {
|
|
19973
|
+
const address = await _getByUserId(user);
|
|
19974
|
+
if (!address) {
|
|
19975
|
+
next(new NotFoundError4("Address not found."));
|
|
19976
|
+
return;
|
|
19977
|
+
}
|
|
19978
|
+
res.json(address);
|
|
19979
|
+
return;
|
|
19980
|
+
} catch (error2) {
|
|
19981
|
+
next(error2);
|
|
19982
|
+
}
|
|
19983
|
+
}
|
|
19984
|
+
return {
|
|
19985
|
+
add,
|
|
19986
|
+
getByUserId
|
|
19987
|
+
};
|
|
19988
|
+
}
|
|
19989
|
+
|
|
19990
|
+
// src/services/organization.service.ts
|
|
19991
|
+
import { NotFoundError as NotFoundError5, useAtlas as useAtlas21 } from "@goweekdays/utils";
|
|
19992
|
+
|
|
19993
|
+
// src/repositories/member.repository.ts
|
|
19994
|
+
import {
|
|
19995
|
+
BadRequestError as BadRequestError36,
|
|
19996
|
+
InternalServerError as InternalServerError20,
|
|
19997
|
+
paginate as paginate10,
|
|
19998
|
+
useAtlas as useAtlas20
|
|
19999
|
+
} from "@goweekdays/utils";
|
|
20000
|
+
|
|
20001
|
+
// src/models/member.model.ts
|
|
20002
|
+
import { BadRequestError as BadRequestError35 } from "@goweekdays/utils";
|
|
20003
|
+
import Joi14 from "joi";
|
|
20004
|
+
import { ObjectId as ObjectId27 } from "mongodb";
|
|
20005
|
+
function MMember(value) {
|
|
20006
|
+
const schema = Joi14.object({
|
|
20007
|
+
_id: Joi14.string().hex().optional().allow("", null),
|
|
20008
|
+
org: Joi14.string().hex().required(),
|
|
20009
|
+
name: Joi14.string().required(),
|
|
20010
|
+
user: Joi14.string().hex().required(),
|
|
20011
|
+
role: Joi14.string().hex().required(),
|
|
20012
|
+
status: Joi14.string().optional().allow("", null),
|
|
20013
|
+
createdAt: Joi14.string().optional().allow("", null),
|
|
20014
|
+
updatedAt: Joi14.string().optional().allow("", null),
|
|
20015
|
+
deletedAt: Joi14.string().optional().allow("", null)
|
|
20016
|
+
});
|
|
20017
|
+
const { error } = schema.validate(value);
|
|
20018
|
+
if (error) {
|
|
20019
|
+
throw new BadRequestError35(error.message);
|
|
20020
|
+
}
|
|
20021
|
+
if (value.org) {
|
|
20022
|
+
try {
|
|
20023
|
+
value.org = new ObjectId27(value.org);
|
|
20024
|
+
} catch (error2) {
|
|
20025
|
+
throw new BadRequestError35("Invalid org ID.");
|
|
20026
|
+
}
|
|
20027
|
+
}
|
|
20028
|
+
if (value.user) {
|
|
20029
|
+
try {
|
|
20030
|
+
value.user = new ObjectId27(value.user);
|
|
20031
|
+
} catch (error2) {
|
|
20032
|
+
throw new BadRequestError35("Invalid user ID.");
|
|
20033
|
+
}
|
|
20034
|
+
}
|
|
20035
|
+
if (value.role) {
|
|
20036
|
+
try {
|
|
20037
|
+
value.role = new ObjectId27(value.role);
|
|
20038
|
+
} catch (error2) {
|
|
20039
|
+
throw new BadRequestError35("Invalid role ID.");
|
|
20040
|
+
}
|
|
20041
|
+
}
|
|
20042
|
+
return {
|
|
20043
|
+
_id: value._id,
|
|
20044
|
+
org: value.org,
|
|
20045
|
+
name: value.name,
|
|
20046
|
+
user: value.user,
|
|
20047
|
+
role: value.role,
|
|
20048
|
+
status: value.status || "active",
|
|
20049
|
+
createdAt: value.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
20050
|
+
updatedAt: "",
|
|
20051
|
+
deletedAt: ""
|
|
20052
|
+
};
|
|
20053
|
+
}
|
|
20054
|
+
|
|
20055
|
+
// src/repositories/member.repository.ts
|
|
20056
|
+
import { ObjectId as ObjectId28 } from "mongodb";
|
|
20057
|
+
function useMemberRepo() {
|
|
20058
|
+
const db = useAtlas20.getDb();
|
|
20059
|
+
if (!db) {
|
|
20060
|
+
throw new Error("Unable to connect to server.");
|
|
20061
|
+
}
|
|
20062
|
+
const collection = db.collection("members");
|
|
20063
|
+
async function createIndex() {
|
|
20064
|
+
try {
|
|
20065
|
+
await collection.createIndex([
|
|
20066
|
+
{
|
|
20067
|
+
name: 1
|
|
20068
|
+
},
|
|
20069
|
+
{
|
|
20070
|
+
status: 1
|
|
20071
|
+
}
|
|
20072
|
+
]);
|
|
20073
|
+
} catch (error) {
|
|
20074
|
+
throw new Error("Failed to create index.");
|
|
20075
|
+
}
|
|
20076
|
+
}
|
|
20077
|
+
async function createUniqueIndex() {
|
|
20078
|
+
try {
|
|
20079
|
+
await collection.createIndex(
|
|
20080
|
+
{
|
|
20081
|
+
org: 1,
|
|
20082
|
+
user: 1
|
|
20083
|
+
},
|
|
20084
|
+
{ partialFilterExpression: { deletedAt: "" }, unique: true }
|
|
20085
|
+
);
|
|
20086
|
+
} catch (error) {
|
|
20087
|
+
throw new Error("Failed to create unique index.");
|
|
20088
|
+
}
|
|
20089
|
+
}
|
|
20090
|
+
async function createTextIndex() {
|
|
20091
|
+
try {
|
|
20092
|
+
await collection.createIndex({
|
|
20093
|
+
name: "text"
|
|
20094
|
+
});
|
|
20095
|
+
} catch (error) {
|
|
20096
|
+
throw new Error("Failed to create text index.");
|
|
20097
|
+
}
|
|
20098
|
+
}
|
|
20099
|
+
async function add(value, session) {
|
|
20100
|
+
try {
|
|
20101
|
+
value = MMember(value);
|
|
20102
|
+
await collection.insertOne(value, { session });
|
|
20103
|
+
return "Successfully added member.";
|
|
20104
|
+
} catch (error) {
|
|
20105
|
+
throw new InternalServerError20("Failed to create member.");
|
|
20106
|
+
}
|
|
20107
|
+
}
|
|
20108
|
+
async function getById(_id) {
|
|
20109
|
+
try {
|
|
20110
|
+
_id = new ObjectId28(_id);
|
|
20111
|
+
} catch (error) {
|
|
20112
|
+
throw new BadRequestError36("Invalid ID.");
|
|
20113
|
+
}
|
|
20114
|
+
try {
|
|
20115
|
+
return await collection.findOne({ _id });
|
|
20116
|
+
} catch (error) {
|
|
20117
|
+
throw new InternalServerError20(
|
|
20118
|
+
"Internal server error, failed to retrieve member."
|
|
20119
|
+
);
|
|
20120
|
+
}
|
|
20121
|
+
}
|
|
20122
|
+
async function getByOrgId(org) {
|
|
20123
|
+
try {
|
|
20124
|
+
org = new ObjectId28(org);
|
|
20125
|
+
} catch (error) {
|
|
20126
|
+
throw new BadRequestError36("Invalid org ID.");
|
|
20127
|
+
}
|
|
20128
|
+
try {
|
|
20129
|
+
return await collection.find({ org }).toArray();
|
|
20130
|
+
} catch (error) {
|
|
20131
|
+
throw new InternalServerError20(
|
|
20132
|
+
"Internal server error, failed to retrieve members."
|
|
20133
|
+
);
|
|
20134
|
+
}
|
|
20135
|
+
}
|
|
20136
|
+
async function getOrgsByUserId({
|
|
20137
|
+
search = "",
|
|
20138
|
+
page = 1,
|
|
20139
|
+
limit = 10,
|
|
20140
|
+
sort = {},
|
|
20141
|
+
user = "",
|
|
20142
|
+
status = "active"
|
|
20143
|
+
} = {}) {
|
|
20144
|
+
page = page > 0 ? page - 1 : 0;
|
|
20145
|
+
try {
|
|
20146
|
+
user = new ObjectId28(user);
|
|
20147
|
+
} catch (error) {
|
|
20148
|
+
throw new BadRequestError36("Invalid user ID.");
|
|
20149
|
+
}
|
|
20150
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
20151
|
+
const query = { user, status };
|
|
20152
|
+
if (search) {
|
|
20153
|
+
query.$text = { $search: search };
|
|
20154
|
+
}
|
|
20155
|
+
try {
|
|
20156
|
+
const items = await collection.aggregate([
|
|
20157
|
+
{ $match: query },
|
|
20158
|
+
{ $sort: sort },
|
|
20159
|
+
{ $skip: page * limit },
|
|
20160
|
+
{
|
|
20161
|
+
$lookup: {
|
|
20162
|
+
from: "orgs",
|
|
20163
|
+
localField: "org",
|
|
20164
|
+
foreignField: "_id",
|
|
20165
|
+
as: "organization"
|
|
20166
|
+
}
|
|
20167
|
+
},
|
|
20168
|
+
{ $unwind: "$organization" },
|
|
20169
|
+
// Flatten the array
|
|
20170
|
+
{
|
|
20171
|
+
$project: { _id: "$organization._id", name: "$organization.name" }
|
|
20172
|
+
}
|
|
20173
|
+
// Extract required fields
|
|
20174
|
+
]).toArray();
|
|
20175
|
+
const length = await collection.countDocuments(query);
|
|
20176
|
+
return paginate10(items, page, limit, length);
|
|
20177
|
+
} catch (error) {
|
|
20178
|
+
throw new InternalServerError20(
|
|
20179
|
+
"Internal server error, failed to retrieve organizations."
|
|
20180
|
+
);
|
|
20181
|
+
}
|
|
20182
|
+
}
|
|
20183
|
+
async function updateStatusByUserId(user, status) {
|
|
20184
|
+
try {
|
|
20185
|
+
user = new ObjectId28(user);
|
|
20186
|
+
} catch (error) {
|
|
20187
|
+
throw new BadRequestError36("Invalid user ID.");
|
|
20188
|
+
}
|
|
20189
|
+
try {
|
|
20190
|
+
await collection.updateMany(
|
|
20191
|
+
{ user },
|
|
20192
|
+
{
|
|
20193
|
+
$set: {
|
|
20194
|
+
status
|
|
20195
|
+
}
|
|
20196
|
+
}
|
|
20197
|
+
);
|
|
20198
|
+
return "Successfully updated member status.";
|
|
20199
|
+
} catch (error) {
|
|
20200
|
+
throw new InternalServerError20("Failed to update member status.");
|
|
20201
|
+
}
|
|
20202
|
+
}
|
|
20203
|
+
return {
|
|
20204
|
+
createIndex,
|
|
20205
|
+
createUniqueIndex,
|
|
20206
|
+
createTextIndex,
|
|
20207
|
+
add,
|
|
20208
|
+
getById,
|
|
20209
|
+
getByOrgId,
|
|
20210
|
+
getOrgsByUserId,
|
|
20211
|
+
updateStatusByUserId
|
|
20212
|
+
};
|
|
20213
|
+
}
|
|
20214
|
+
|
|
20215
|
+
// src/services/organization.service.ts
|
|
20216
|
+
function useOrgService() {
|
|
20217
|
+
const { add: addOrg } = useOrgRepo();
|
|
20218
|
+
const { addRole } = useRoleRepo();
|
|
20219
|
+
const { add: addMember } = useMemberRepo();
|
|
20220
|
+
const { getUserById } = useUserRepo();
|
|
20221
|
+
async function createOrg({ user = "", name = "", description = "" } = {}) {
|
|
20222
|
+
const session = useAtlas21.getClient()?.startSession();
|
|
20223
|
+
session?.startTransaction();
|
|
20224
|
+
try {
|
|
20225
|
+
const _user = await getUserById(user);
|
|
20226
|
+
if (!_user) {
|
|
20227
|
+
throw new NotFoundError5("User not found.");
|
|
20228
|
+
}
|
|
20229
|
+
const org = await addOrg(
|
|
20230
|
+
{
|
|
20231
|
+
name,
|
|
20232
|
+
description
|
|
20233
|
+
},
|
|
20234
|
+
session
|
|
20235
|
+
);
|
|
20236
|
+
const role = await addRole(
|
|
20237
|
+
{
|
|
20238
|
+
org,
|
|
20239
|
+
name: "Owner",
|
|
20240
|
+
description: "Owner of the organization",
|
|
20241
|
+
permissions: ["all"]
|
|
20242
|
+
},
|
|
20243
|
+
session
|
|
20244
|
+
);
|
|
20245
|
+
await addMember(
|
|
20246
|
+
{
|
|
20247
|
+
name: `${_user.firstName} ${_user.lastName}`,
|
|
20248
|
+
org,
|
|
20249
|
+
user,
|
|
20250
|
+
role
|
|
20251
|
+
},
|
|
20252
|
+
session
|
|
20253
|
+
);
|
|
20254
|
+
session?.commitTransaction();
|
|
20255
|
+
return "Organization created successfully.";
|
|
20256
|
+
} catch (error) {
|
|
20257
|
+
session?.abortTransaction();
|
|
20258
|
+
throw error;
|
|
20259
|
+
} finally {
|
|
20260
|
+
session?.endSession();
|
|
20261
|
+
}
|
|
20262
|
+
}
|
|
20263
|
+
return {
|
|
20264
|
+
createOrg
|
|
20265
|
+
};
|
|
20266
|
+
}
|
|
20267
|
+
|
|
20268
|
+
// src/controllers/organization.controller.ts
|
|
20269
|
+
import {
|
|
20270
|
+
BadRequestError as BadRequestError37
|
|
20271
|
+
} from "@goweekdays/utils";
|
|
20272
|
+
import Joi15 from "joi";
|
|
20273
|
+
function useOrgController() {
|
|
20274
|
+
const { createOrg: _createOrg } = useOrgService();
|
|
20275
|
+
const { getOrgsByUserId: _getOrgsByUserId } = useMemberRepo();
|
|
20276
|
+
async function createOrg(req, res, next) {
|
|
20277
|
+
const value = req.body;
|
|
20278
|
+
const validation = Joi15.object({
|
|
20279
|
+
name: Joi15.string().required(),
|
|
20280
|
+
type: Joi15.string().required(),
|
|
20281
|
+
email: Joi15.string().email().required(),
|
|
20282
|
+
contact: Joi15.string().required(),
|
|
20283
|
+
description: Joi15.string().required(),
|
|
20284
|
+
user: Joi15.string().hex().required()
|
|
20285
|
+
});
|
|
20286
|
+
const { error } = validation.validate(value);
|
|
20287
|
+
if (error) {
|
|
20288
|
+
next(new BadRequestError37(error.message));
|
|
20289
|
+
return;
|
|
20290
|
+
}
|
|
20291
|
+
try {
|
|
20292
|
+
const message = await _createOrg(value);
|
|
20293
|
+
res.json({ message });
|
|
20294
|
+
return;
|
|
20295
|
+
} catch (error2) {
|
|
20296
|
+
next(error2);
|
|
20297
|
+
}
|
|
20298
|
+
}
|
|
20299
|
+
async function getOrgsByUserId(req, res, next) {
|
|
20300
|
+
const page = Number(req.query.page) ?? 0;
|
|
20301
|
+
const limit = Number(req.query.limit) ?? 10;
|
|
20302
|
+
const search = req.query.search ?? "";
|
|
20303
|
+
const user = req.headers["user"];
|
|
20304
|
+
const validation = Joi15.object({
|
|
20305
|
+
user: Joi15.string().hex().required(),
|
|
20306
|
+
page: Joi15.number().min(1).optional().allow("", null),
|
|
20307
|
+
limit: Joi15.number().min(1).optional().allow("", null),
|
|
20308
|
+
search: Joi15.string().optional().allow("", null)
|
|
20309
|
+
});
|
|
20310
|
+
const { error } = validation.validate({ user, page, limit, search });
|
|
20311
|
+
if (error) {
|
|
20312
|
+
next(new BadRequestError37(error.message));
|
|
20313
|
+
return;
|
|
20314
|
+
}
|
|
20315
|
+
try {
|
|
20316
|
+
const orgs = await _getOrgsByUserId({ user, page, limit, search });
|
|
20317
|
+
res.json(orgs);
|
|
20318
|
+
return;
|
|
20319
|
+
} catch (error2) {
|
|
20320
|
+
next(error2);
|
|
20321
|
+
}
|
|
20322
|
+
}
|
|
20323
|
+
return {
|
|
20324
|
+
createOrg,
|
|
20325
|
+
getOrgsByUserId
|
|
18852
20326
|
};
|
|
18853
20327
|
}
|
|
18854
20328
|
export {
|
|
@@ -18865,12 +20339,16 @@ export {
|
|
|
18865
20339
|
MAILER_TRANSPORT_HOST,
|
|
18866
20340
|
MAILER_TRANSPORT_PORT,
|
|
18867
20341
|
MAILER_TRANSPORT_SECURE,
|
|
20342
|
+
MAddress,
|
|
18868
20343
|
MCapBldgAct,
|
|
18869
20344
|
MComment,
|
|
18870
20345
|
MEntity,
|
|
18871
20346
|
MFile,
|
|
20347
|
+
MMember,
|
|
18872
20348
|
MONGO_DB,
|
|
18873
20349
|
MONGO_URI,
|
|
20350
|
+
MOrg,
|
|
20351
|
+
MPaymentMethod,
|
|
18874
20352
|
MRole,
|
|
18875
20353
|
MSubscription,
|
|
18876
20354
|
MToken,
|
|
@@ -18895,7 +20373,11 @@ export {
|
|
|
18895
20373
|
SPACES_SECRET_KEY,
|
|
18896
20374
|
VERIFICATION_FORGET_PASSWORD_DURATION,
|
|
18897
20375
|
VERIFICATION_USER_INVITE_DURATION,
|
|
20376
|
+
XENDIT_BASE_URL,
|
|
20377
|
+
XENDIT_SECRET_KEY,
|
|
18898
20378
|
isDev,
|
|
20379
|
+
useAddressController,
|
|
20380
|
+
useAddressRepo,
|
|
18899
20381
|
useAuthController,
|
|
18900
20382
|
useAuthService,
|
|
18901
20383
|
useCapBldgActController,
|
|
@@ -18910,6 +20392,13 @@ export {
|
|
|
18910
20392
|
useFileController,
|
|
18911
20393
|
useFileRepo,
|
|
18912
20394
|
useFileService,
|
|
20395
|
+
useMemberRepo,
|
|
20396
|
+
useOrgController,
|
|
20397
|
+
useOrgRepo,
|
|
20398
|
+
useOrgService,
|
|
20399
|
+
usePaymentMethodController,
|
|
20400
|
+
usePaymentMethodRepo,
|
|
20401
|
+
usePaymentMethodService,
|
|
18913
20402
|
useRoleController,
|
|
18914
20403
|
useRoleRepo,
|
|
18915
20404
|
useRoleService,
|
|
@@ -18925,7 +20414,8 @@ export {
|
|
|
18925
20414
|
useVerificationService,
|
|
18926
20415
|
useWorkflowController,
|
|
18927
20416
|
useWorkflowRepo,
|
|
18928
|
-
useWorkflowService
|
|
20417
|
+
useWorkflowService,
|
|
20418
|
+
useXenditService
|
|
18929
20419
|
};
|
|
18930
20420
|
/*! Bundled license information:
|
|
18931
20421
|
|