Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix bugs and update dependencies #45

Merged
merged 1 commit into from
Feb 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@types/jsonwebtoken": "^9.0.4",
"@types/mongoose": "^5.11.97",
"@types/node": "^20.8.7",
"@types/node-cron": "^3.0.11",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"eslint": "^8.56.0",
Expand Down Expand Up @@ -43,6 +44,7 @@
"googleapis": "^128.0.0",
"jsonwebtoken": "^9.0.2",
"mongoose": "^7.6.3",
"node-cron": "^3.0.3",
"zod": "^3.22.4",
"zod-express-middleware": "^1.4.0"
}
Expand Down
6 changes: 5 additions & 1 deletion src/controllers/service.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ export const getServicesController = ApiHandler(
const services = await getServicesOfDiscordGuilds(guildIds);
const servicesWithGuilds = services.map((service) => {
const guild = guilds.find((guild) => guild.id === service.guildId);
if (!guild) throw new Error("Guild not found");
return {
...service,
guild:{...guild,icon:`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.webp`},
guild: {
...guild,
icon: `https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.webp`,
},
};
});
return res.send({
Expand Down
40 changes: 22 additions & 18 deletions src/customSolutions/customIntegrations/tagMango/apiWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import axios from "axios";
import { createCredential, getCredential } from "./models/tmCredential.model";
import {
createCredential,
getCredential,
} from "./services/tmCredential.service";

export const getOtp = async (
data: { phone: number; userAgent: string },
Expand Down Expand Up @@ -32,6 +35,7 @@ export const verifyOtp = async (
},
customerId: string,
domain: string,
serviceId: string,
) => {
const config = {
method: "post",
Expand All @@ -43,7 +47,7 @@ export const verifyOtp = async (
},
data: {
...data,
logoutAll: true,
// logoutAll: true,
},
};
const response = await axios(config);
Expand All @@ -57,24 +61,24 @@ export const verifyOtp = async (
refreshToken: result.refreshToken,
phone: data.phone,
domain,
serviceId,
});
if (!credential.acknowledged) {
throw new Error("Error in creating credential");
}
return true;
};

export const getAccessToken = async (customerId: string) => {
const credential = await getCredential(customerId);
export const getAccessToken = async (serviceId: string) => {
const credential = await getCredential(serviceId);
if (!credential) throw new Error("Credential not found");

// If token is valid for more than 80 minutes, return it
// If token updated in less than 80 minutes, return it
// if (credential.updatedAt.getTime() + 80 * 60 * 1000 > Date.now())
// return {
// accessToken: credential.accessToken,
// domain: credential.domain,
// };

const { refreshToken } = credential;
const config = {
method: "post",
Expand All @@ -94,11 +98,11 @@ export const getAccessToken = async (customerId: string) => {
throw new Error("Error in getting access token");

const data = await createCredential({
customerId,
accessToken: result.accessToken,
refreshToken: result.refreshToken,
phone: credential.phone,
domain: credential.domain,
serviceId,
});
if (!data.acknowledged)
throw new Error("Error in updating credential with new token");
Expand All @@ -112,9 +116,9 @@ export const getAccessToken = async (customerId: string) => {
export const getSubscribers = async ({
page = 1,
type = "all",
pageSize = 25,
pageSize,
mangoes,
customerId,
serviceId,
term,
startDate,
endDate,
Expand All @@ -123,12 +127,12 @@ export const getSubscribers = async ({
type?: "all" | "active" | "inactive" | "revoked";
pageSize?: number;
mangoes: string;
customerId: string;
serviceId: string;
term?: string | number;
startDate?: string;
endDate?: string;
}) => {
const credential = await getAccessToken(customerId);
const credential = await getAccessToken(serviceId);
const config = {
method: "get",
maxBodyLength: Infinity,
Expand All @@ -137,7 +141,7 @@ export const getSubscribers = async ({
"x-whitelabel-host": credential.domain,
"Content-Type": "application/json",
authorization: `Bearer ${credential.accessToken}`,
"x-whitelabel-creator": await getHostDetails(customerId),
"x-whitelabel-creator": await getHostDetails(serviceId),
},
params: {
page,
Expand All @@ -147,7 +151,7 @@ export const getSubscribers = async ({
term,
startDate,
endDate,
spreadSubscribers: true,
// spreadSubscribers: true,
},
};
const response = await axios(config);
Expand All @@ -159,15 +163,15 @@ export const getSubscribers = async ({
throw result;
};

export const getAllActiveMangoes = async (customerId: string) => {
const credential = await getAccessToken(customerId);
export const getAllActiveMangoes = async (serviceId: string) => {
const credential = await getAccessToken(serviceId);
const config = {
method: "get",
maxBodyLength: Infinity,
url: "https://api-prod-new.tagmango.com/get-all-active-mangoes",
headers: {
"x-whitelabel-host": credential.domain,
"x-whitelabel-creator": await getHostDetails(customerId),
"x-whitelabel-creator": await getHostDetails(serviceId),
authorization: `Bearer ${credential.accessToken}`,
},
};
Expand All @@ -180,8 +184,8 @@ export const getAllActiveMangoes = async (customerId: string) => {
throw result;
};

export const getHostDetails = async (customerId: string) => {
const credential = await getAccessToken(customerId);
export const getHostDetails = async (serviceId: string) => {
const credential = await getAccessToken(serviceId);
const config = {
method: "get",
maxBodyLength: Infinity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export type TmSubscriberDocument = mongoose.Document & {
country: string;
linkedDiscord: boolean;
discordLinkTimestamp: Date;
updatedAt: Date;
createdAt: Date;
Comment on lines +12 to +13
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

};

const TmSubscriberSchema = new mongoose.Schema(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import mongoose from "mongoose";
import { CustomerDocument } from "../../../../models/mongoDB/customer.model";
import { CustomerDocument } from "@/models/mongoDB/customer.model";
import { ServiceDocument } from "@/models/mongoDB/service.model";

export type TmCredentialDocument = mongoose.Document & {
customer: mongoose.PopulatedDoc<CustomerDocument & mongoose.Document>;
accessToken: string; // 1.5 hours
refreshToken: string; // 1 month
phone: number;
domain: string;
service: mongoose.PopulatedDoc<ServiceDocument & mongoose.Document>;
createdAt: Date;
updatedAt: Date;
};
Expand All @@ -17,12 +19,16 @@ const TmCredentialSchema = new mongoose.Schema(
type: mongoose.Schema.Types.ObjectId,
ref: "customer",
required: true,
unique: true,
},
accessToken: { type: String, required: true },
refreshToken: { type: String, required: true },
phone: { type: Number, required: true },
domain: { type: String, required: true },
service: {
type: mongoose.Schema.Types.ObjectId,
ref: "service",
required: true,
},
},
{ timestamps: true },
);
Expand All @@ -31,31 +37,3 @@ const model = mongoose.model<TmCredentialDocument>(
TmCredentialSchema,
);
export default model;

export const createCredential = async ({
customerId,
accessToken,
refreshToken,
phone,
domain,
}: {
customerId: string;
accessToken: string;
refreshToken: string;
phone: number;
domain: string;
}) => {
const credential = await model
.updateOne(
{ customer: customerId },
{ accessToken, refreshToken, phone, domain },
{ upsert: true },
)
.exec();
return credential;
};

export const getCredential = async (customerId: string) => {
const credential = await model.findOne({ customer: customerId }).exec();
return credential;
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export type TmMapperDocument = mongoose.Document & {
TmCredentialDocument & mongoose.Document
>;
customer: mongoose.PopulatedDoc<CustomerDocument & mongoose.Document>;
xWhiteLabelHost: string;
metadata: object;
customIntegrationId: string;
};
Expand Down Expand Up @@ -39,52 +38,3 @@ const TmMapperSchema = new mongoose.Schema(
);
const model = mongoose.model<TmMapperDocument>("tmMapper", TmMapperSchema);
export default model;

export const createMapper = async ({
mango,
serviceId,
tmCredentialId,
customerId,
metadata,
customIntegrationId,
}: {
mango: string;
serviceId: string;
tmCredentialId: string;
customerId: string;
metadata: object;
customIntegrationId: string;
}) => {
const mapper = await model.create({
mango,
service: serviceId,
tmCredential: tmCredentialId,
customer: customerId,
metadata,
customIntegrationId,
});
return mapper;
};

export const getMapper = async (
{
mango,
serviceId,
customerId,
}: {
mango?: string;
serviceId?: string;
customerId?: string;
},
populated = true,
) => {
const mapper = await model
.findOne({
mango,
service: serviceId,
customer: customerId,
})
.populate(populated ? ["service", "tmCredential", "customer"] : [])
.exec();
return mapper;
};
30 changes: 20 additions & 10 deletions src/customSolutions/customIntegrations/tagMango/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import serviceModel from "@/models/mongoDB/service.model";
import { Router } from "express";
import { getAllActiveMangoes, getOtp, verifyOtp } from "../apiWrapper";
import { getCredential } from "../models/tmCredential.model";
import { createMapper } from "../models/tmMapper.model";
import { getCredential } from "../services/tmCredential.service";
import { createMapper } from "../services/tmMapper.service";
const router = Router();

// Get OTP
Expand Down Expand Up @@ -37,13 +37,18 @@ router.post("/getOtp", async (req, res) => {
// Verify OTP
router.post("/verifyOtp", async (req, res) => {
try {
const { phone, otp, domain } = req.body;
const { phone, otp, domain, serviceId } = req.body;
const data = {
phone,
otp,
userAgent: req.headers["user-agent"] || "",
};
const verified = await verifyOtp(data, req.customer.id, domain);
const verified = await verifyOtp(
data,
req.customer.id,
domain,
serviceId,
);
if (verified) {
res.status(200).send({
message: "OTP verified successfully",
Expand All @@ -64,9 +69,12 @@ router.post("/verifyOtp", async (req, res) => {

router.get("/mangoes", async (req, res) => {
try {
const credential = await getCredential(req.customer.id);
if (!req.query.serviceId) throw new Error("ServiceId not found");
const credential = await getCredential(req.query.serviceId as string);
if (!credential) throw new Error("Credential not found");
const mangoes = await getAllActiveMangoes(req.customer.id);
const mangoes = await getAllActiveMangoes(
req.query.serviceId as string,
);
if (!mangoes) throw new Error("No mangoes found");

const data = mangoes.map((mango: any) => {
Expand Down Expand Up @@ -99,22 +107,24 @@ router.post("/addCustomSolution", async (req, res) => {
const service = await serviceModel.findById(serviceId).exec();
if (!service) throw new Error("Service not found");

const mangoes = await getAllActiveMangoes(req.customer.id);
const mangoes = await getAllActiveMangoes(serviceId);
if (!mangoes.find((m: any) => m._id === mango))
throw new Error("Mango not found in TagMango");

const mapper = await createMapper({
mango,
serviceId,
customerId: req.customer.id,
tmCredentialId: (await getCredential(req.customer.id))?._id,
tmCredentialId: (await getCredential(serviceId))?._id,
metadata: {},
customIntegrationId: service.customIntegrationId,
});
res.status(200).send({
if (!mapper) throw new Error("Error in creating mapper");

return res.status(200).send({
message: "Custom TagMango Service created successfully",
});
} catch (error) {
} catch (error: any) {
if (error.name === "MongoServerError") {
if (error.code === 11000) {
return res.status(400).send({
Expand Down