mirror of
https://github.com/towfiqi/serpbear
synced 2025-06-26 18:15:54 +00:00
- Previously only domain properties worked with SerpBear. This feature adds the ability to add URL properties as well. - Adds a new field "search_console" in Domain Table. - Adds a new Search Console option in Domain Settings Modal UI. - When the new "This is a URL Property" option is enabled, the exact Property URL should be provided. closes #50
125 lines
4.7 KiB
TypeScript
125 lines
4.7 KiB
TypeScript
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
import db from '../../database/database';
|
|
import Domain from '../../database/models/domain';
|
|
import Keyword from '../../database/models/keyword';
|
|
import getdomainStats from '../../utils/domains';
|
|
import verifyUser from '../../utils/verifyUser';
|
|
import { removeLocalSCData } from '../../utils/searchConsole';
|
|
|
|
type DomainsGetRes = {
|
|
domains: DomainType[]
|
|
error?: string|null,
|
|
}
|
|
|
|
type DomainsAddResponse = {
|
|
domains: DomainType[]|null,
|
|
error?: string|null,
|
|
}
|
|
|
|
type DomainsDeleteRes = {
|
|
domainRemoved: number,
|
|
keywordsRemoved: number,
|
|
SCDataRemoved: boolean,
|
|
error?: string|null,
|
|
}
|
|
|
|
type DomainsUpdateRes = {
|
|
domain: Domain|null,
|
|
error?: string|null,
|
|
}
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
await db.sync();
|
|
const authorized = verifyUser(req, res);
|
|
if (authorized !== 'authorized') {
|
|
return res.status(401).json({ error: authorized });
|
|
}
|
|
if (req.method === 'GET') {
|
|
return getDomains(req, res);
|
|
}
|
|
if (req.method === 'POST') {
|
|
return addDomain(req, res);
|
|
}
|
|
if (req.method === 'DELETE') {
|
|
return deleteDomain(req, res);
|
|
}
|
|
if (req.method === 'PUT') {
|
|
return updateDomain(req, res);
|
|
}
|
|
return res.status(502).json({ error: 'Unrecognized Route.' });
|
|
}
|
|
|
|
export const getDomains = async (req: NextApiRequest, res: NextApiResponse<DomainsGetRes>) => {
|
|
const withStats = !!req?.query?.withstats;
|
|
try {
|
|
const allDomains: Domain[] = await Domain.findAll();
|
|
const formattedDomains: DomainType[] = allDomains.map((el) => el.get({ plain: true }));
|
|
const theDomains: DomainType[] = withStats ? await getdomainStats(formattedDomains) : allDomains;
|
|
return res.status(200).json({ domains: theDomains });
|
|
} catch (error) {
|
|
return res.status(400).json({ domains: [], error: 'Error Getting Domains.' });
|
|
}
|
|
};
|
|
|
|
const addDomain = async (req: NextApiRequest, res: NextApiResponse<DomainsAddResponse>) => {
|
|
const { domains } = req.body;
|
|
if (domains && Array.isArray(domains) && domains.length > 0) {
|
|
const domainsToAdd: any = [];
|
|
|
|
domains.forEach((domain: string) => {
|
|
domainsToAdd.push({
|
|
domain: domain.trim(),
|
|
slug: domain.trim().replaceAll('-', '_').replaceAll('.', '-').replaceAll('/', '-'),
|
|
lastUpdated: new Date().toJSON(),
|
|
added: new Date().toJSON(),
|
|
});
|
|
});
|
|
try {
|
|
const newDomains:Domain[] = await Domain.bulkCreate(domainsToAdd);
|
|
const formattedDomains = newDomains.map((el) => el.get({ plain: true }));
|
|
return res.status(201).json({ domains: formattedDomains });
|
|
} catch (error) {
|
|
console.log('[ERROR] Adding New Domain ', error);
|
|
return res.status(400).json({ domains: [], error: 'Error Adding Domain.' });
|
|
}
|
|
} else {
|
|
return res.status(400).json({ domains: [], error: 'Necessary data missing.' });
|
|
}
|
|
};
|
|
|
|
export const deleteDomain = async (req: NextApiRequest, res: NextApiResponse<DomainsDeleteRes>) => {
|
|
if (!req.query.domain && typeof req.query.domain !== 'string') {
|
|
return res.status(400).json({ domainRemoved: 0, keywordsRemoved: 0, SCDataRemoved: false, error: 'Domain is Required!' });
|
|
}
|
|
try {
|
|
const { domain } = req.query || {};
|
|
const removedDomCount: number = await Domain.destroy({ where: { domain } });
|
|
const removedKeywordCount: number = await Keyword.destroy({ where: { domain } });
|
|
const SCDataRemoved = await removeLocalSCData(domain as string);
|
|
return res.status(200).json({ domainRemoved: removedDomCount, keywordsRemoved: removedKeywordCount, SCDataRemoved });
|
|
} catch (error) {
|
|
console.log('[ERROR] Deleting Domain: ', req.query.domain, error);
|
|
return res.status(400).json({ domainRemoved: 0, keywordsRemoved: 0, SCDataRemoved: false, error: 'Error Deleting Domain' });
|
|
}
|
|
};
|
|
|
|
export const updateDomain = async (req: NextApiRequest, res: NextApiResponse<DomainsUpdateRes>) => {
|
|
if (!req.query.domain) {
|
|
return res.status(400).json({ domain: null, error: 'Domain is Required!' });
|
|
}
|
|
const { domain } = req.query || {};
|
|
const { notification_interval, notification_emails, search_console } = req.body as DomainSettings;
|
|
|
|
try {
|
|
const domainToUpdate: Domain|null = await Domain.findOne({ where: { domain } });
|
|
if (domainToUpdate) {
|
|
domainToUpdate.set({ notification_interval, notification_emails, search_console: JSON.stringify(search_console) });
|
|
await domainToUpdate.save();
|
|
}
|
|
return res.status(200).json({ domain: domainToUpdate });
|
|
} catch (error) {
|
|
console.log('[ERROR] Updating Domain: ', req.query.domain, error);
|
|
return res.status(400).json({ domain: null, error: 'Error Updating Domain' });
|
|
}
|
|
};
|