diff --git a/components/forms/ChangePasswordForm.js b/components/forms/ChangePasswordForm.js
index 4ee657e6..dcad6f17 100644
--- a/components/forms/ChangePasswordForm.js
+++ b/components/forms/ChangePasswordForm.js
@@ -9,7 +9,7 @@ import FormLayout, {
FormRow,
} from 'components/layout/FormLayout';
import useApi from 'hooks/useApi';
-import useUser from '../../hooks/useUser';
+import useUser from 'hooks/useUser';
const initialValues = {
current_password: '',
@@ -43,13 +43,13 @@ export default function ChangePasswordForm({ values, onSave, onClose }) {
const { user } = useUser();
const handleSubmit = async values => {
- const { ok, data } = await post(`/accounts/${user.userId}/password`, values);
+ const { ok, error } = await post(`/accounts/${user.accountUuid}/password`, values);
if (ok) {
onSave();
} else {
setMessage(
- data || ,
+ error || ,
);
}
};
diff --git a/lib/auth.js b/lib/auth.js
index 446d5169..f43f2002 100644
--- a/lib/auth.js
+++ b/lib/auth.js
@@ -1,6 +1,6 @@
import { parseSecureToken, parseToken } from 'next-basics';
-import { getWebsite } from 'queries';
-import { SHARE_TOKEN_HEADER } from 'lib/constants';
+import { getAccount, getWebsite } from 'queries';
+import { SHARE_TOKEN_HEADER, TYPE_ACCOUNT, TYPE_WEBSITE } from 'lib/constants';
import { secret } from 'lib/crypto';
export function getAuthToken(req) {
@@ -35,7 +35,7 @@ export function isValidToken(token, validation) {
return false;
}
-export async function allowQuery(req) {
+export async function allowQuery(req, type) {
const { id } = req.query;
const { userId, isAdmin, shareToken } = req.auth ?? {};
@@ -49,9 +49,15 @@ export async function allowQuery(req) {
}
if (userId) {
- const website = await getWebsite({ id });
+ if (type === TYPE_WEBSITE) {
+ const website = await getWebsite({ websiteUuid: id });
- return website && website.userId === userId;
+ return website && website.userId === userId;
+ } else if (type === TYPE_ACCOUNT) {
+ const account = await getAccount({ accountUuid: id });
+
+ return account && account.id === id;
+ }
}
return false;
diff --git a/lib/constants.js b/lib/constants.js
index feef540d..8b3ee8d0 100644
--- a/lib/constants.js
+++ b/lib/constants.js
@@ -21,6 +21,9 @@ export const DEFAULT_WEBSITE_LIMIT = 10;
export const REALTIME_RANGE = 30;
export const REALTIME_INTERVAL = 3000;
+export const TYPE_WEBSITE = 'website';
+export const TYPE_ACCOUNT = 'account';
+
export const THEME_COLORS = {
light: {
primary: '#2680eb',
diff --git a/lib/session.js b/lib/session.js
index acd5b6b0..d1a88768 100644
--- a/lib/session.js
+++ b/lib/session.js
@@ -4,7 +4,7 @@ import { secret, uuid } from 'lib/crypto';
import redis, { DELETED } from 'lib/redis';
import clickhouse from 'lib/clickhouse';
import { getClientInfo, getJsonBody } from 'lib/request';
-import { createSession, getSessionByUuid, getWebsiteByUuid } from 'queries';
+import { createSession, getSessionByUuid, getWebsite } from 'queries';
export async function getSession(req) {
const { payload } = getJsonBody(req);
@@ -38,7 +38,7 @@ export async function getSession(req) {
// Check database if does not exists in Redis
if (!websiteId) {
- const website = await getWebsiteByUuid(websiteUuid);
+ const website = await getWebsite({ websiteUuid });
websiteId = website ? website.id : null;
}
diff --git a/pages/api/accounts/[id]/password.js b/pages/api/accounts/[id]/password.js
index 3a46c56a..89649c20 100644
--- a/pages/api/accounts/[id]/password.js
+++ b/pages/api/accounts/[id]/password.js
@@ -1,4 +1,4 @@
-import { getAccountById, updateAccount } from 'queries';
+import { getAccount, updateAccount } from 'queries';
import { useAuth } from 'lib/middleware';
import {
badRequest,
@@ -8,21 +8,21 @@ import {
checkPassword,
hashPassword,
} from 'next-basics';
+import { allowQuery } from 'lib/auth';
+import { TYPE_ACCOUNT } from 'lib/constants';
export default async (req, res) => {
await useAuth(req, res);
- const { userId: currentUserId, isAdmin: currentUserIsAdmin } = req.auth;
const { current_password, new_password } = req.body;
- const { id } = req.query;
- const userId = +id;
+ const { id: accountUuid } = req.query;
- if (!currentUserIsAdmin && userId !== currentUserId) {
+ if (!(await allowQuery(req, TYPE_ACCOUNT))) {
return unauthorized(res);
}
if (req.method === 'POST') {
- const account = await getAccountById(userId);
+ const account = await getAccount({ accountUuid });
if (!checkPassword(current_password, account.password)) {
return badRequest(res, 'Current password is incorrect');
@@ -30,7 +30,7 @@ export default async (req, res) => {
const password = hashPassword(new_password);
- const updated = await updateAccount(userId, { password });
+ const updated = await updateAccount({ password }, { accountUuid });
return ok(res, updated);
}
diff --git a/pages/api/accounts/index.js b/pages/api/accounts/index.js
index aa52ca55..5addd63a 100644
--- a/pages/api/accounts/index.js
+++ b/pages/api/accounts/index.js
@@ -1,7 +1,7 @@
import { ok, unauthorized, methodNotAllowed, badRequest, hashPassword } from 'next-basics';
import { useAuth } from 'lib/middleware';
import { uuid } from 'lib/crypto';
-import { createAccount, getAccountByUsername, getAccounts } from 'queries';
+import { createAccount, getAccount, getAccounts } from 'queries';
export default async (req, res) => {
await useAuth(req, res);
@@ -21,7 +21,7 @@ export default async (req, res) => {
if (req.method === 'POST') {
const { username, password, account_uuid } = req.body;
- const accountByUsername = await getAccountByUsername(username);
+ const accountByUsername = await getAccount({ username });
if (accountByUsername) {
return badRequest(res, 'Account already exists');
diff --git a/pages/api/auth/login.js b/pages/api/auth/login.js
index d5379a22..aa4803d8 100644
--- a/pages/api/auth/login.js
+++ b/pages/api/auth/login.js
@@ -1,5 +1,5 @@
import { ok, unauthorized, badRequest, checkPassword, createSecureToken } from 'next-basics';
-import { getAccountByUsername } from 'queries/admin/account/getAccountByUsername';
+import { getAccount } from 'queries';
import { secret } from 'lib/crypto';
export default async (req, res) => {
@@ -9,7 +9,7 @@ export default async (req, res) => {
return badRequest(res);
}
- const account = await getAccountByUsername(username);
+ const account = await getAccount({ username });
if (account && checkPassword(password, account.password)) {
const { id, username, isAdmin, accountUuid } = account;
diff --git a/pages/api/share/[id].js b/pages/api/share/[id].js
index a89829fa..4ff6b81c 100644
--- a/pages/api/share/[id].js
+++ b/pages/api/share/[id].js
@@ -1,4 +1,4 @@
-import { getWebsiteByShareId } from 'queries';
+import { getWebsite } from 'queries';
import { ok, notFound, methodNotAllowed, createToken } from 'next-basics';
import { secret } from 'lib/crypto';
@@ -6,7 +6,7 @@ export default async (req, res) => {
const { id } = req.query;
if (req.method === 'GET') {
- const website = await getWebsiteByShareId(id);
+ const website = await getWebsite({ shareId: id });
if (website) {
const { websiteUuid } = website;
diff --git a/pages/api/websites/[id]/active.js b/pages/api/websites/[id]/active.js
index 10e73ea8..59af938e 100644
--- a/pages/api/websites/[id]/active.js
+++ b/pages/api/websites/[id]/active.js
@@ -2,13 +2,14 @@ import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { allowQuery } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware';
import { getActiveVisitors } from 'queries';
+import { TYPE_WEBSITE } from 'lib/constants';
export default async (req, res) => {
await useCors(req, res);
await useAuth(req, res);
if (req.method === 'GET') {
- if (!(await allowQuery(req))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
diff --git a/pages/api/websites/[id]/eventdata.js b/pages/api/websites/[id]/eventdata.js
index 86a17b77..0e6ad2e9 100644
--- a/pages/api/websites/[id]/eventdata.js
+++ b/pages/api/websites/[id]/eventdata.js
@@ -3,13 +3,14 @@ import { getEventData } from 'queries';
import { ok, badRequest, methodNotAllowed, unauthorized } from 'next-basics';
import { allowQuery } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware';
+import { TYPE_WEBSITE } from 'lib/constants';
export default async (req, res) => {
await useCors(req, res);
await useAuth(req, res);
if (req.method === 'POST') {
- if (!(await allowQuery(req))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
diff --git a/pages/api/websites/[id]/events.js b/pages/api/websites/[id]/events.js
index 192e284a..da88794e 100644
--- a/pages/api/websites/[id]/events.js
+++ b/pages/api/websites/[id]/events.js
@@ -3,6 +3,7 @@ import { getEventMetrics } from 'queries';
import { ok, badRequest, methodNotAllowed, unauthorized } from 'next-basics';
import { allowQuery } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware';
+import { TYPE_WEBSITE } from 'lib/constants';
const unitTypes = ['year', 'month', 'hour', 'day'];
@@ -11,7 +12,7 @@ export default async (req, res) => {
await useAuth(req, res);
if (req.method === 'GET') {
- if (!(await allowQuery(req))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
diff --git a/pages/api/websites/[id]/index.js b/pages/api/websites/[id]/index.js
index d802982a..539a3288 100644
--- a/pages/api/websites/[id]/index.js
+++ b/pages/api/websites/[id]/index.js
@@ -2,19 +2,20 @@ import { allowQuery } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware';
import { getRandomChars, methodNotAllowed, ok, serverError, unauthorized } from 'next-basics';
import { deleteWebsite, getAccount, getWebsite, updateWebsite } from 'queries';
+import { TYPE_WEBSITE } from 'lib/constants';
export default async (req, res) => {
await useCors(req, res);
await useAuth(req, res);
- const { id: websiteId } = req.query;
+ const { id: websiteUuid } = req.query;
- if (!(await allowQuery(req))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
if (req.method === 'GET') {
- const website = await getWebsite({ websiteUuid: websiteId });
+ const website = await getWebsite({ websiteUuid });
return ok(res, website);
}
@@ -32,7 +33,7 @@ export default async (req, res) => {
}
}
- const website = await getWebsite({ websiteUuid: websiteId });
+ const website = await getWebsite({ websiteUuid });
const newShareId = enableShareUrl ? website.shareId || getRandomChars(8) : null;
@@ -44,7 +45,7 @@ export default async (req, res) => {
shareId: shareId ? shareId : newShareId,
userId: account ? account.id : +owner || undefined,
},
- { websiteUuid: websiteId },
+ { websiteUuid },
);
} catch (e) {
if (e.message.includes('Unique constraint') && e.message.includes('share_id')) {
@@ -56,11 +57,11 @@ export default async (req, res) => {
}
if (req.method === 'DELETE') {
- if (!(await allowQuery(req, true))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
- await deleteWebsite(websiteId);
+ await deleteWebsite(websiteUuid);
return ok(res);
}
diff --git a/pages/api/websites/[id]/metrics.js b/pages/api/websites/[id]/metrics.js
index e0eab028..0aafe7d3 100644
--- a/pages/api/websites/[id]/metrics.js
+++ b/pages/api/websites/[id]/metrics.js
@@ -1,8 +1,8 @@
import { allowQuery } from 'lib/auth';
-import { FILTER_IGNORED } from 'lib/constants';
+import { FILTER_IGNORED, TYPE_WEBSITE } from 'lib/constants';
import { useAuth, useCors } from 'lib/middleware';
import { badRequest, methodNotAllowed, ok, unauthorized } from 'next-basics';
-import { getPageviewMetrics, getSessionMetrics, getWebsiteByUuid } from 'queries';
+import { getPageviewMetrics, getSessionMetrics, getWebsite } from 'queries';
const sessionColumns = ['browser', 'os', 'device', 'screen', 'country', 'language'];
const pageviewColumns = ['url', 'referrer', 'query'];
@@ -38,7 +38,7 @@ export default async (req, res) => {
await useAuth(req, res);
if (req.method === 'GET') {
- if (!(await allowQuery(req))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
@@ -94,7 +94,7 @@ export default async (req, res) => {
let domain;
if (type === 'referrer') {
- const website = await getWebsiteByUuid(websiteId);
+ const website = await getWebsite({ websiteUuid: websiteId });
if (!website) {
return badRequest(res);
diff --git a/pages/api/websites/[id]/pageviews.js b/pages/api/websites/[id]/pageviews.js
index 9e05417b..5b628e3a 100644
--- a/pages/api/websites/[id]/pageviews.js
+++ b/pages/api/websites/[id]/pageviews.js
@@ -3,6 +3,7 @@ import { getPageviewStats } from 'queries';
import { ok, badRequest, methodNotAllowed, unauthorized } from 'next-basics';
import { allowQuery } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware';
+import { TYPE_WEBSITE } from 'lib/constants';
const unitTypes = ['year', 'month', 'hour', 'day'];
@@ -11,7 +12,7 @@ export default async (req, res) => {
await useAuth(req, res);
if (req.method === 'GET') {
- if (!(await allowQuery(req))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
diff --git a/pages/api/websites/[id]/reset.js b/pages/api/websites/[id]/reset.js
index fe527ad4..0dde02df 100644
--- a/pages/api/websites/[id]/reset.js
+++ b/pages/api/websites/[id]/reset.js
@@ -2,6 +2,7 @@ import { resetWebsite } from 'queries';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { allowQuery } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware';
+import { TYPE_WEBSITE } from 'lib/constants';
export default async (req, res) => {
await useCors(req, res);
@@ -10,7 +11,7 @@ export default async (req, res) => {
const { id: websiteId } = req.query;
if (req.method === 'POST') {
- if (!(await allowQuery(req))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
diff --git a/pages/api/websites/[id]/stats.js b/pages/api/websites/[id]/stats.js
index 596ebc90..2c5b0156 100644
--- a/pages/api/websites/[id]/stats.js
+++ b/pages/api/websites/[id]/stats.js
@@ -2,13 +2,14 @@ import { getWebsiteStats } from 'queries';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { allowQuery } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware';
+import { TYPE_WEBSITE } from 'lib/constants';
export default async (req, res) => {
await useCors(req, res);
await useAuth(req, res);
if (req.method === 'GET') {
- if (!(await allowQuery(req))) {
+ if (!(await allowQuery(req, TYPE_WEBSITE))) {
return unauthorized(res);
}
diff --git a/queries/admin/account/getAccountById.js b/queries/admin/account/getAccountById.js
deleted file mode 100644
index eee1b76a..00000000
--- a/queries/admin/account/getAccountById.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import prisma from 'lib/prisma';
-
-export async function getAccountById(userId) {
- return prisma.client.account.findUnique({
- where: {
- id: userId,
- },
- });
-}
diff --git a/queries/admin/account/getAccountByUsername.js b/queries/admin/account/getAccountByUsername.js
deleted file mode 100644
index ff64c8ce..00000000
--- a/queries/admin/account/getAccountByUsername.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import prisma from 'lib/prisma';
-
-export async function getAccountByUsername(username) {
- return prisma.client.account.findUnique({
- where: {
- username,
- },
- });
-}
diff --git a/queries/admin/website/deleteWebsite.js b/queries/admin/website/deleteWebsite.js
index b5e2ff76..f08dc63e 100644
--- a/queries/admin/website/deleteWebsite.js
+++ b/queries/admin/website/deleteWebsite.js
@@ -1,27 +1,24 @@
import prisma from 'lib/prisma';
import redis, { DELETED } from 'lib/redis';
-import { getWebsiteByUuid } from 'queries';
-export async function deleteWebsite(websiteId) {
+export async function deleteWebsite(websiteUuid) {
const { client, transaction } = prisma;
- const { websiteUuid } = await getWebsiteByUuid(websiteId);
-
return transaction([
client.pageview.deleteMany({
- where: { session: { website: { websiteUuid: websiteId } } },
+ where: { session: { website: { websiteUuid } } },
}),
client.eventData.deleteMany({
- where: { event: { session: { website: { websiteUuid: websiteId } } } },
+ where: { event: { session: { website: { websiteUuid } } } },
}),
client.event.deleteMany({
- where: { session: { website: { websiteUuid: websiteId } } },
+ where: { session: { website: { websiteUuid } } },
}),
client.session.deleteMany({
- where: { website: { websiteUuid: websiteId } },
+ where: { website: { websiteUuid } },
}),
client.website.delete({
- where: { websiteUuid: websiteId },
+ where: { websiteUuid },
}),
]).then(async res => {
if (redis.client) {
diff --git a/queries/admin/website/getWebsite.js b/queries/admin/website/getWebsite.js
index 83c3e83a..d33c9ead 100644
--- a/queries/admin/website/getWebsite.js
+++ b/queries/admin/website/getWebsite.js
@@ -1,7 +1,16 @@
import prisma from 'lib/prisma';
+import redis from 'lib/redis';
export async function getWebsite(where) {
- return prisma.client.website.findUnique({
- where,
- });
+ return prisma.client.website
+ .findUnique({
+ where,
+ })
+ .then(async data => {
+ if (redis.enabled && data) {
+ await redis.client.set(`website:${data.websiteUuid}`, data.id);
+ }
+
+ return data;
+ });
}
diff --git a/queries/admin/website/getWebsiteById.js b/queries/admin/website/getWebsiteById.js
deleted file mode 100644
index f486bd8f..00000000
--- a/queries/admin/website/getWebsiteById.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import prisma from 'lib/prisma';
-
-export async function getWebsiteById(websiteId) {
- return prisma.client.website.findUnique({
- where: {
- id: websiteId,
- },
- });
-}
diff --git a/queries/admin/website/getWebsiteByShareId.js b/queries/admin/website/getWebsiteByShareId.js
deleted file mode 100644
index bfc99ce7..00000000
--- a/queries/admin/website/getWebsiteByShareId.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import prisma from 'lib/prisma';
-
-export async function getWebsiteByShareId(shareId) {
- return prisma.client.website.findUnique({
- where: {
- shareId,
- },
- });
-}
diff --git a/queries/admin/website/getWebsiteByUuid.js b/queries/admin/website/getWebsiteByUuid.js
deleted file mode 100644
index 158d357a..00000000
--- a/queries/admin/website/getWebsiteByUuid.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import prisma from 'lib/prisma';
-import redis from 'lib/redis';
-
-export async function getWebsiteByUuid(websiteUuid) {
- return prisma.client.website
- .findUnique({
- where: {
- websiteUuid,
- },
- })
- .then(async res => {
- if (redis.client && res) {
- await redis.client.set(`website:${res.websiteUuid}`, res.id);
- }
-
- return res;
- });
-}
diff --git a/queries/index.js b/queries/index.js
index abff147a..a570af65 100644
--- a/queries/index.js
+++ b/queries/index.js
@@ -1,8 +1,6 @@
export * from './admin/account/createAccount';
export * from './admin/account/deleteAccount';
export * from './admin/account/getAccount';
-export * from './admin/account/getAccountById';
-export * from './admin/account/getAccountByUsername';
export * from './admin/account/getAccounts';
export * from './admin/account/updateAccount';
export * from './admin/website/createWebsite';
@@ -10,9 +8,6 @@ export * from './admin/website/deleteWebsite';
export * from './admin/website/getAllWebsites';
export * from './admin/website/getUserWebsites';
export * from './admin/website/getWebsite';
-export * from './admin/website/getWebsiteById';
-export * from './admin/website/getWebsiteByShareId';
-export * from './admin/website/getWebsiteByUuid';
export * from './admin/website/resetWebsite';
export * from './admin/website/updateWebsite';
export * from './analytics/event/getEventMetrics';