added functionality for user subscriptions
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
import { v4 } from 'uuid';
|
||||||
|
import { CheckboxType } from '../../util/types';
|
||||||
|
|
||||||
|
// designed to be consumed by the Form class
|
||||||
|
const Checkbox = () => {
|
||||||
|
return ( <></>
|
||||||
|
// <div id={rowid} key={v4()}>
|
||||||
|
// <label>{label}</label>
|
||||||
|
// <input
|
||||||
|
// type="checkbox"
|
||||||
|
// id={id}
|
||||||
|
// onChange={(e) => FormElement.update(e, idx)}>
|
||||||
|
// </input>
|
||||||
|
// </div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ChangeEvent } from "react";
|
import { ChangeEvent, ChangeEventHandler } from "react";
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,9 +35,15 @@ export default class Form<T>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(e: ChangeEvent<HTMLElement>, idx: number) {
|
update(e: ChangeEvent<HTMLElement>, idx: number) {
|
||||||
let newState = {
|
let newState;
|
||||||
...this.state,
|
|
||||||
[this.keys[idx]]: e.target['value' as keyof EventTarget]
|
if (this.dataTypes[idx] == 'checkbox') {
|
||||||
|
newState = { ...this.state }
|
||||||
|
} else {
|
||||||
|
newState = {
|
||||||
|
...this.state,
|
||||||
|
[this.keys[idx]]: e.target['value' as keyof EventTarget]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state = newState;
|
this.state = newState;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Dispatch, FC, ReactNode, SetStateAction } from "react";
|
import { ChangeEvent, ChangeEventHandler, Dispatch, FC, ReactNode, SetStateAction } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { Form } from "../components/ui";
|
||||||
import { IUser } from "../schemas";
|
import { IUser } from "../schemas";
|
||||||
|
|
||||||
interface PortalBase {
|
interface PortalBase {
|
||||||
@@ -25,9 +26,20 @@ interface NavbarProps {
|
|||||||
liftChange?: (newValue: IUser | undefined) => void
|
liftChange?: (newValue: IUser | undefined) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CheckboxProps {
|
||||||
|
rowid: string
|
||||||
|
id: string
|
||||||
|
idx: number
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
onChange: (e: ChangeEvent<HTMLElement>, idx: number) => void
|
||||||
|
FormElement: typeof Form
|
||||||
|
}
|
||||||
|
|
||||||
export type PageComponent = FC<PortalBase>
|
export type PageComponent = FC<PortalBase>
|
||||||
export type PanelComponent = FC<PortalBase>
|
export type PanelComponent = FC<PortalBase>
|
||||||
export type ButtonComponent = FC<ButtonParams>
|
export type ButtonComponent = FC<ButtonParams>
|
||||||
export type ProtectPortal = FC<MultiChildPortal>
|
export type ProtectPortal = FC<MultiChildPortal>
|
||||||
export type UserCardType = FC<UserCardProps>
|
export type UserCardType = FC<UserCardProps>
|
||||||
export type NavbarType = FC<NavbarProps>
|
export type NavbarType = FC<NavbarProps>
|
||||||
|
export type CheckboxType = FC<CheckboxProps>
|
||||||
@@ -14,6 +14,7 @@ export default class AuthService {
|
|||||||
data.datecreated = now;
|
data.datecreated = now;
|
||||||
data.datemodified = now;
|
data.datemodified = now;
|
||||||
data.active = true;
|
data.active = true;
|
||||||
|
data.isadmin = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const user = await UserInstance.getOneByEmail(email);
|
const user = await UserInstance.getOneByEmail(email);
|
||||||
@@ -29,7 +30,6 @@ export default class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await UserInstance.post(newData);
|
const result = await UserInstance.post(newData);
|
||||||
if (result) console.log(result);
|
|
||||||
return result;
|
return result;
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -46,7 +46,6 @@ export default class AuthService {
|
|||||||
const user = await UserInstance.getOneByEmail(email);
|
const user = await UserInstance.getOneByEmail(email);
|
||||||
if (!user) return { ok: false, user: null }
|
if (!user) return { ok: false, user: null }
|
||||||
const match = await bcrypt.compare(password, user.password);
|
const match = await bcrypt.compare(password, user.password);
|
||||||
console.log(match);
|
|
||||||
return {
|
return {
|
||||||
ok: match,
|
ok: match,
|
||||||
user: match ? user : null
|
user: match ? user : null
|
||||||
|
|||||||
@@ -6,4 +6,16 @@ export function restrictAccess(req: Request, res: Response, next: NextFunction)
|
|||||||
} else {
|
} else {
|
||||||
res.send({ ok: false, user: undefined })
|
res.send({ ok: false, user: undefined })
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkSubscription(req: Request, res: Response, next: NextFunction) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkFriendStatus(req: Request, res: Response, next: NextFunction) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkIsAdmin(req: Request, res: Response, next: NextFunction) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,4 +21,20 @@ export default class CollectionCtl {
|
|||||||
if (!result) throw createError('400', 'Bad request');
|
if (!result) throw createError('400', 'Bad request');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSubscriptions(userid: string) {
|
||||||
|
const result = await CollectionInstance.getSubscriptions(userid);
|
||||||
|
if (!result) throw createError('404', 'No subscriptions found');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async postSubscription(collectionid: string, userid: string) {
|
||||||
|
const { ok, code, data } = await CollectionInstance.postSubscription(collectionid, userid);
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
throw createError(code, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,13 +6,13 @@ export default async function populate() {
|
|||||||
|
|
||||||
const populateUsers = `
|
const populateUsers = `
|
||||||
INSERT INTO recipin.appusers
|
INSERT INTO recipin.appusers
|
||||||
(firstname, lastname, handle, email, password, active, datecreated, datemodified)
|
(firstname, lastname, handle, email, password, active, isadmin, datecreated, datemodified)
|
||||||
VALUES
|
VALUES
|
||||||
('Mikayla', 'Dobson', 'innocuoussymmetry', 'mikaylaherself@gmail.com', 'password1', true, $1, $1),
|
('Mikayla', 'Dobson', 'innocuoussymmetry', 'mikaylaherself@gmail.com', 'password1', true, true, $1, $1),
|
||||||
('Emily', 'Dobson', 'emjdobson', 'emily@email.com', 'password2', true, $1, $1),
|
('Emily', 'Dobson', 'emjdobson', 'emily@email.com', 'password2', true, false, $1, $1),
|
||||||
('Montanna', 'Dobson', 'delayedlemon', 'montanna@email.com', 'password3', true, $1, $1),
|
('Montanna', 'Dobson', 'delayedlemon', 'montanna@email.com', 'password3', true, false, $1, $1),
|
||||||
('Christine', 'Riley', 'christine', 'christine@email.com', 'password4', true, $1, $1),
|
('Christine', 'Riley', 'christine', 'christine@email.com', 'password4', true, false, $1, $1),
|
||||||
('Someone', 'Not active', 'someone', 'someone@email.com', 'notactive', false, $1, $1)
|
('Someone', 'Not active', 'someone', 'someone@email.com', 'notactive', false, false, $1, $1)
|
||||||
;
|
;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ CREATE TABLE IF NOT EXISTS recipin.appusers (
|
|||||||
email varchar NOT NULL UNIQUE,
|
email varchar NOT NULL UNIQUE,
|
||||||
password varchar NOT NULL,
|
password varchar NOT NULL,
|
||||||
active boolean NOT NULL,
|
active boolean NOT NULL,
|
||||||
|
isadmin boolean NOT NULL,
|
||||||
datecreated varchar NOT NULL,
|
datecreated varchar NOT NULL,
|
||||||
datemodified varchar NOT NULL
|
datemodified varchar NOT NULL
|
||||||
);
|
);
|
||||||
3
server/db/sql/derived/checksubscription.sql
Normal file
3
server/db/sql/derived/checksubscription.sql
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
-- SELECT * FROM cmp_usersubscriptions
|
||||||
|
-- WHERE usermemberid = $1
|
||||||
|
-- AND collectionid = $2;
|
||||||
13
server/db/sql/get/getsubscriptions.sql
Normal file
13
server/db/sql/get/getsubscriptions.sql
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
SELECT
|
||||||
|
recipin.cmp_usersubscriptions.collectionid as collectionid,
|
||||||
|
recipin.collection.ownerid as ownerid,
|
||||||
|
recipin.cmp_usersubscriptions.usermemberid as memberid,
|
||||||
|
recipin.collection.name as collectionname,
|
||||||
|
recipin.appusers.firstname as owner_first,
|
||||||
|
recipin.appusers.lastname as owner_last
|
||||||
|
FROM recipin.collection
|
||||||
|
INNER JOIN recipin.appusers
|
||||||
|
ON recipin.collection.ownerid = recipin.appusers.id
|
||||||
|
INNER JOIN recipin.cmp_usersubscriptions
|
||||||
|
ON recipin.collection.id = recipin.cmp_usersubscriptions.collectionid
|
||||||
|
WHERE recipin.cmp_usersubscriptions.usermemberid = $1;
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
import { ICollection } from "../schemas";
|
import { ICollection, IUser } from "../schemas";
|
||||||
|
import { User } from "./user";
|
||||||
|
import { appRoot } from "../appRoot";
|
||||||
|
import now from "../util/now";
|
||||||
import pool from "../db";
|
import pool from "../db";
|
||||||
|
import fs from 'fs';
|
||||||
|
const UserInstance = new User();
|
||||||
export class Collection {
|
export class Collection {
|
||||||
async getOne(id: string) {
|
async getOne(id: string) {
|
||||||
try {
|
try {
|
||||||
@@ -31,11 +35,11 @@ export class Collection {
|
|||||||
try {
|
try {
|
||||||
const statement = `
|
const statement = `
|
||||||
INSERT INTO recipin.collection
|
INSERT INTO recipin.collection
|
||||||
(name, active, ismaincollection, ownerid)
|
(name, active, ismaincollection, ownerid, datecreated, datemodified)
|
||||||
VALUES ($1, $2, $3, $4)
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
`
|
`
|
||||||
const values = [name, active, ismaincollection, ownerid];
|
const values = [name, (active || true), (ismaincollection || false), ownerid, now, now];
|
||||||
const result = await pool.query(statement, values);
|
const result = await pool.query(statement, values);
|
||||||
if (result.rows.length) return result.rows;
|
if (result.rows.length) return result.rows;
|
||||||
return null;
|
return null;
|
||||||
@@ -43,4 +47,92 @@ export class Collection {
|
|||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSubscriptions(userid: string) {
|
||||||
|
try {
|
||||||
|
const sql = fs.readFileSync(appRoot + '/db/sql/get/getsubscriptions.sql').toString();
|
||||||
|
console.log(sql);
|
||||||
|
const result = await pool.query(sql, [userid]);
|
||||||
|
if (result.rows.length) return result.rows;
|
||||||
|
return null;
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async postSubscription(collectionid: string, userid: string): Promise<{ ok: boolean, code: number, data: string | any[] }> {
|
||||||
|
try {
|
||||||
|
// ensure user exists
|
||||||
|
const user: IUser | null = await UserInstance.getOneByID(userid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
code: 404,
|
||||||
|
data: "User not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure collection exists
|
||||||
|
const target: ICollection | null = await this.getOne(collectionid);
|
||||||
|
if (!target) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
code: 404,
|
||||||
|
data: "Collection not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure a user cannot subscribe to their own collection
|
||||||
|
if (target.ownerid == parseInt(userid)) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
code: 403,
|
||||||
|
data: "User cannot subscribe to their own collection"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure a duplicate subscription does not exist
|
||||||
|
const allSubscriptions = `
|
||||||
|
SELECT * FROM recipin.cmp_usersubscriptions
|
||||||
|
WHERE collectionid = $1;
|
||||||
|
`
|
||||||
|
const subscriptionResult = await pool.query(allSubscriptions, [collectionid]);
|
||||||
|
if (subscriptionResult.rows?.length) {
|
||||||
|
for (let row of subscriptionResult.rows) {
|
||||||
|
if (row.usermemberid == parseInt(userid)) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
code: 403,
|
||||||
|
data: "This user is already subscribed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally, execute insertion
|
||||||
|
const statement = `
|
||||||
|
INSERT INTO recipin.cmp_usersubscriptions
|
||||||
|
(collectionid, usermemberid)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
RETURNING *;
|
||||||
|
`
|
||||||
|
|
||||||
|
const result = await pool.query(statement, [collectionid, userid]);
|
||||||
|
if (result.rows.length) {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
code: 201,
|
||||||
|
data: result.rows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
code: 400,
|
||||||
|
data: "Bad request. No data returned."
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ import fs from "fs";
|
|||||||
import pgPromise from "pg-promise";
|
import pgPromise from "pg-promise";
|
||||||
import pool from '../db';
|
import pool from '../db';
|
||||||
import now from "../util/now";
|
import now from "../util/now";
|
||||||
import { appRoot } from "..";
|
import { appRoot } from "../appRoot";
|
||||||
|
|
||||||
const pgp = pgPromise({ capSQL: true });
|
const pgp = pgPromise({ capSQL: true });
|
||||||
export class User {
|
export class User {
|
||||||
@@ -73,7 +73,7 @@ export class User {
|
|||||||
|
|
||||||
|
|
||||||
async post(data: IUser) {
|
async post(data: IUser) {
|
||||||
const { firstname, lastname, handle, email, password, active } = data;
|
const { firstname, lastname, handle, email, password, active, isadmin } = data;
|
||||||
const datecreated = now;
|
const datecreated = now;
|
||||||
const datemodified = now;
|
const datemodified = now;
|
||||||
|
|
||||||
@@ -81,11 +81,11 @@ export class User {
|
|||||||
const statement = `
|
const statement = `
|
||||||
INSERT INTO recipin.appusers (
|
INSERT INTO recipin.appusers (
|
||||||
firstname, lastname, handle, email, password,
|
firstname, lastname, handle, email, password,
|
||||||
active, datecreated, datemodified)
|
active, isadmin, datecreated, datemodified)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
`;
|
`;
|
||||||
const params = [firstname, lastname, handle, email, password, active, datecreated, datemodified];
|
const params = [firstname, lastname, handle, email, password, active, isadmin, datecreated, datemodified];
|
||||||
const result = await pool.query(statement, params);
|
const result = await pool.query(statement, params);
|
||||||
if (result.rows.length) return result.rows;
|
if (result.rows.length) return result.rows;
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const authRoute = (app: Express, passport: PassportStatic) => {
|
|||||||
router.get('/', restrictAccess, (req, res, next) => {
|
router.get('/', restrictAccess, (req, res, next) => {
|
||||||
// @ts-ignore: does not recognize structure of req.user
|
// @ts-ignore: does not recognize structure of req.user
|
||||||
const user = req.user?.user;
|
const user = req.user?.user;
|
||||||
const userData: IUser = {
|
const userData = {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
firstname: user.firstname,
|
firstname: user.firstname,
|
||||||
lastname: user.lastname,
|
lastname: user.lastname,
|
||||||
@@ -41,9 +41,7 @@ export const authRoute = (app: Express, passport: PassportStatic) => {
|
|||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
console.log('login successful');
|
console.log('login successful');
|
||||||
})
|
})
|
||||||
// const { id, email, handle, firstname, lastname } = response.user;
|
|
||||||
// await UserControl.updateOne(response.user.id, { ...response.user, datemodified: now })
|
|
||||||
// res.status(200).send({ id: id, handle: handle, firstname: firstname, lastname: lastname });
|
|
||||||
res.cookie('userid', response.user.id, { maxAge: 1000 * 60 * 60 * 24 });
|
res.cookie('userid', response.user.id, { maxAge: 1000 * 60 * 60 * 24 });
|
||||||
res.send(response);
|
res.send(response);
|
||||||
res.end();
|
res.end();
|
||||||
@@ -70,8 +68,6 @@ export const authRoute = (app: Express, passport: PassportStatic) => {
|
|||||||
router.post('/register', async (req, res, next) => {
|
router.post('/register', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const data: IUser = req.body;
|
const data: IUser = req.body;
|
||||||
const now = new Intl.DateTimeFormat('en-US', {})
|
|
||||||
|
|
||||||
const response = await AuthInstance.register(data);
|
const response = await AuthInstance.register(data);
|
||||||
res.status(200).send(response);
|
res.status(200).send(response);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Express, Router } from "express";
|
import { Express, Router } from "express";
|
||||||
|
import { restrictAccess } from "../auth/middlewares";
|
||||||
import CollectionCtl from "../controllers/CollectionCtl";
|
import CollectionCtl from "../controllers/CollectionCtl";
|
||||||
const CollectionInstance = new CollectionCtl();
|
const CollectionInstance = new CollectionCtl();
|
||||||
|
|
||||||
@@ -7,7 +8,7 @@ const router = Router();
|
|||||||
export const collectionRoute = (app: Express) => {
|
export const collectionRoute = (app: Express) => {
|
||||||
app.use('/collection', router);
|
app.use('/collection', router);
|
||||||
|
|
||||||
router.get('/:id', async (req, res, next) => {
|
router.get('/:id', restrictAccess, async (req, res, next) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
try {
|
try {
|
||||||
const result = await CollectionInstance.getOne(id);
|
const result = await CollectionInstance.getOne(id);
|
||||||
@@ -17,7 +18,8 @@ export const collectionRoute = (app: Express) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get('/', async (req, res, next) => {
|
// implement is admin on this route
|
||||||
|
router.get('/', restrictAccess, async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const result = await CollectionInstance.getAll();
|
const result = await CollectionInstance.getAll();
|
||||||
res.status(200).send(result);
|
res.status(200).send(result);
|
||||||
@@ -26,7 +28,7 @@ export const collectionRoute = (app: Express) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
router.post('/', async (req, res, next) => {
|
router.post('/', restrictAccess, async (req, res, next) => {
|
||||||
const data = req.body;
|
const data = req.body;
|
||||||
try {
|
try {
|
||||||
const result = await CollectionInstance.post(data);
|
const result = await CollectionInstance.post(data);
|
||||||
@@ -35,4 +37,31 @@ export const collectionRoute = (app: Express) => {
|
|||||||
next(e);
|
next(e);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// router.get('/subscriptions', restrictAccess, async (req, res, next) => {
|
||||||
|
// res.send('sanity check');
|
||||||
|
// // // @ts-ignore
|
||||||
|
// // const { user } = req.user;
|
||||||
|
// // if (!user) return;
|
||||||
|
|
||||||
|
// // try {
|
||||||
|
// // const result = await CollectionInstance.getSubscriptions("9");
|
||||||
|
// // res.status(200).send(result);
|
||||||
|
// // } catch(e) {
|
||||||
|
// // next(e);
|
||||||
|
// // }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// router.post('/subscribe', restrictAccess, async (req, res, next) => {
|
||||||
|
// // @ts-ignore
|
||||||
|
// const { user } = req.user;
|
||||||
|
// const { collection } = req.query;
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const result = await CollectionInstance.postSubscription(collection as string, user.id as string);
|
||||||
|
// res.status(201).send(result);
|
||||||
|
// } catch(e) {
|
||||||
|
// next(e);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ import { collectionRoute } from "./collection";
|
|||||||
import { ingredientRoute } from "./ingredient";
|
import { ingredientRoute } from "./ingredient";
|
||||||
import { groceryListRoute } from "./groceryList";
|
import { groceryListRoute } from "./groceryList";
|
||||||
import { authRoute } from "./auth";
|
import { authRoute } from "./auth";
|
||||||
|
import { subscriptionRoute } from "./subscriptions";
|
||||||
|
|
||||||
export const routes = async (app: Express, passport: PassportStatic) => {
|
export const routes = async (app: Express, passport: PassportStatic) => {
|
||||||
console.log('routes called');
|
console.log('routes called');
|
||||||
@@ -14,6 +15,7 @@ export const routes = async (app: Express, passport: PassportStatic) => {
|
|||||||
userRoute(app);
|
userRoute(app);
|
||||||
recipeRoute(app);
|
recipeRoute(app);
|
||||||
collectionRoute(app);
|
collectionRoute(app);
|
||||||
|
subscriptionRoute(app);
|
||||||
ingredientRoute(app);
|
ingredientRoute(app);
|
||||||
groceryListRoute(app);
|
groceryListRoute(app);
|
||||||
}
|
}
|
||||||
39
server/routes/subscriptions.ts
Normal file
39
server/routes/subscriptions.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { Express, Router } from "express"
|
||||||
|
import { restrictAccess } from "../auth/middlewares";
|
||||||
|
import { CollectionCtl } from "../controllers";
|
||||||
|
const CollectionInstance = new CollectionCtl();
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
export const subscriptionRoute = (app: Express) => {
|
||||||
|
app.use('/subscription', router);
|
||||||
|
|
||||||
|
router.get('/', async (req, res, next) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const { user } = req.user;
|
||||||
|
if (!user) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await CollectionInstance.getSubscriptions(user.id as string);
|
||||||
|
res.status(200).send(result);
|
||||||
|
} catch(e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
router.post('/', restrictAccess, async (req, res, next) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const { user } = req.user;
|
||||||
|
const { collection } = req.query;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await CollectionInstance.postSubscription(collection as string, user.id as string);
|
||||||
|
res.status(201).send(result);
|
||||||
|
} catch(e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
router.put('/', async (req, res, next) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
// defined shared characteristics for DB entities
|
||||||
|
interface DBEntity {
|
||||||
|
id?: number
|
||||||
|
}
|
||||||
|
|
||||||
interface HasHistory extends DBEntity {
|
interface HasHistory extends DBEntity {
|
||||||
datecreated?: string
|
datecreated?: string
|
||||||
datemodified?: string
|
datemodified?: string
|
||||||
@@ -7,15 +12,13 @@ interface CanDeactivate extends DBEntity {
|
|||||||
active?: boolean
|
active?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DBEntity {
|
// data models
|
||||||
id?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IUser extends HasHistory, CanDeactivate {
|
export interface IUser extends HasHistory, CanDeactivate {
|
||||||
firstname: string
|
firstname: string
|
||||||
lastname: string
|
lastname: string
|
||||||
handle: string
|
handle: string
|
||||||
email: string
|
email: string
|
||||||
|
isadmin: boolean
|
||||||
password?: string
|
password?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +31,7 @@ export interface IRecipe extends HasHistory, CanDeactivate {
|
|||||||
name: string
|
name: string
|
||||||
description?: string
|
description?: string
|
||||||
preptime: string
|
preptime: string
|
||||||
authoruserid?: IUser["id"]
|
authoruserid: IUser["id"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IIngredient extends HasHistory {
|
export interface IIngredient extends HasHistory {
|
||||||
@@ -39,10 +42,10 @@ export interface IIngredient extends HasHistory {
|
|||||||
export interface ICollection extends HasHistory, CanDeactivate {
|
export interface ICollection extends HasHistory, CanDeactivate {
|
||||||
name: string
|
name: string
|
||||||
ismaincollection: boolean
|
ismaincollection: boolean
|
||||||
ownerid?: IUser["id"]
|
ownerid: IUser["id"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IGroceryList extends HasHistory, CanDeactivate {
|
export interface IGroceryList extends HasHistory, CanDeactivate {
|
||||||
name: string
|
name: string
|
||||||
ownerid?: IUser["id"]
|
ownerid: IUser["id"]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user