auth mw stuff
This commit is contained in:
1 parent
d868baade5
commit
a79c11496b
8 files changed
+166
-31
No files matched your search
@@ -3,11 +3,9 @@ import { getCookies, setCookie } from "$std/http/cookie.ts"
|
|||||||
import { createPg } from "api/pg.ts"
|
import { createPg } from "api/pg.ts"
|
||||||
|
|
||||||
// Define public paths that don't require authentication
|
// Define public paths that don't require authentication
|
||||||
const PUBLIC_PATHS = [
|
const PROTECTED = [
|
||||||
"/",
|
"/home",
|
||||||
"/api/auth/login",
|
"/api/auth",
|
||||||
"/api/auth/register",
|
|
||||||
"/api/auth/logout",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
// Sessions storage shared between routes
|
// Sessions storage shared between routes
|
||||||
@@ -18,11 +16,8 @@ export async function authMiddleware(req: Request, ctx: FreshContext): Promise<R
|
|||||||
const url = new URL(req.url)
|
const url = new URL(req.url)
|
||||||
const path = url.pathname
|
const path = url.pathname
|
||||||
|
|
||||||
console.log("authing...")
|
|
||||||
|
|
||||||
// Allow public paths without authentication
|
// Allow public paths without authentication
|
||||||
if (PUBLIC_PATHS.includes(path)) {
|
if (!PROTECTED.includes(path)) {
|
||||||
console.log("noauth")
|
|
||||||
return await ctx.next()
|
return await ctx.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +61,6 @@ export async function authMiddleware(req: Request, ctx: FreshContext): Promise<R
|
|||||||
ctx.state.user = user
|
ctx.state.user = user
|
||||||
ctx.state.pg = pg
|
ctx.state.pg = pg
|
||||||
|
|
||||||
console.log("woas")
|
|
||||||
|
|
||||||
return await ctx.next()
|
return await ctx.next()
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
import type Log from 'bunyan';
|
||||||
|
import type { PrismaClient, Want, User, Listing, Offer, } from '@prisma/client';
|
||||||
|
import assert from 'assert/strict';
|
||||||
|
import groupBy from 'lodash/groupBy';
|
||||||
|
import sortBy from 'lodash/sortBy';
|
||||||
|
import flatMap from 'lodash/flatMap';
|
||||||
|
import { Context } from 'koa';
|
||||||
|
|
||||||
|
import { logAxiosError, wantDetails } from './utils';
|
||||||
|
import { Pg } from './pg';
|
||||||
|
|
||||||
|
export enum Status {
|
||||||
|
Complete = 'Complete',
|
||||||
|
Confirmed = 'Confirmed',
|
||||||
|
Accepted = 'Accepted',
|
||||||
|
Pending = 'Pending',
|
||||||
|
Declined = 'Declined',
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortOffers(o) {
|
||||||
|
return Object.values(Status).indexOf(o.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function createOffers(log: Log, pg: Pg) {
|
||||||
|
async function generate() {
|
||||||
|
const listings = flatMap(await pg.interestingListings());
|
||||||
|
log.debug('generateOffers', { listings: listings.length });
|
||||||
|
|
||||||
|
const shipping = 7.5; // yolt
|
||||||
|
|
||||||
|
const offers = listings.map(l => ({
|
||||||
|
userId: l.want.user.id,
|
||||||
|
listingId: l.id,
|
||||||
|
wantId: l.want.id,
|
||||||
|
|
||||||
|
status: Status.Pending,
|
||||||
|
|
||||||
|
condition: l.data.condition,
|
||||||
|
|
||||||
|
item: l.data.price.value,
|
||||||
|
shipping,
|
||||||
|
total: l.data.price.value + shipping,
|
||||||
|
}))
|
||||||
|
|
||||||
|
// we must sort the offers by price,
|
||||||
|
// sometimes a seller has multiples of a want
|
||||||
|
// to deal with this we just ignore duplicates on insert
|
||||||
|
// and ensure the cheapest one goes in first
|
||||||
|
const sorted = sortBy(offers, ['item']);
|
||||||
|
|
||||||
|
// TODO probably need to take one of each condition of record from a store
|
||||||
|
// eg. they have a VG+ and a M we should make offers for each
|
||||||
|
|
||||||
|
log.trace('generated offers', sorted);
|
||||||
|
const inserts = await pg.offersUpdate(sorted);
|
||||||
|
|
||||||
|
return inserts;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function accept(ctx: Context) {
|
||||||
|
const { id } = ctx.request.body;
|
||||||
|
ctx.assert(id, 401, 'no id supplied');
|
||||||
|
|
||||||
|
// check the user actually has this offer
|
||||||
|
const offer = await pg.userOfferFind(ctx.state.user, id);
|
||||||
|
return pg.offerStatusSet([offer.id], Status.Accepted);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function statusSet(user: User, ids: UUID[], status: Status) {
|
||||||
|
log.info({ status, ids }, 'setting offer status');
|
||||||
|
|
||||||
|
// const offer = await pg.offerFindId(ids);
|
||||||
|
const update = await pg.offerStatusSet(ids, status);
|
||||||
|
|
||||||
|
// forget about this for now
|
||||||
|
// if (status === Status.Complete) {
|
||||||
|
// log.info({ id, status }, 'completed offer, removing want...');
|
||||||
|
// await pg.wantRm(offer.wantId);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return update;
|
||||||
|
}
|
||||||
|
|
||||||
|
// converts offers into groups based on seller
|
||||||
|
// includes some bits of info about shipping etc
|
||||||
|
async function acpOffers() {
|
||||||
|
const offers = await pg.offersAdmin();
|
||||||
|
|
||||||
|
const grouped = groupBy(offers, o => o.listing.data.seller.id);
|
||||||
|
|
||||||
|
const sellerOffers = sortBy(Object.values(grouped).map(offers => {
|
||||||
|
const shipping = offers[0]?.listing.data.seller.shipping;
|
||||||
|
const bundle = {
|
||||||
|
username: offers[0]?.listing.data.seller.username,
|
||||||
|
seller: offers[0]?.listing.data.seller.id,
|
||||||
|
shipsFrom: offers[0]?.listing.data.ships_from,
|
||||||
|
shipping,
|
||||||
|
offers: sortBy(offers, sortOffers),
|
||||||
|
mentionsAustralia: shipping.toLowerCase().includes('australia'),
|
||||||
|
mentionsWorldwide: shipping.toLowerCase().includes('world'),
|
||||||
|
}
|
||||||
|
|
||||||
|
return bundle;
|
||||||
|
}), bundle => -bundle.offers.length);
|
||||||
|
|
||||||
|
return sellerOffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// also groups offers by seller for users
|
||||||
|
// but mostly just munges the structure so the details
|
||||||
|
// are easily available
|
||||||
|
async function userOffers(user: User) {
|
||||||
|
const offers = await pg.userOffers(user);
|
||||||
|
const groups = Object.values(groupBy(offers, (o) => o.wantId))
|
||||||
|
.map(g => {
|
||||||
|
// the offer status is just the most advanced status
|
||||||
|
// based on sort
|
||||||
|
const offers = sortBy(g, sortOffers);
|
||||||
|
const status = offers[0].status;
|
||||||
|
|
||||||
|
// now actually sort them by price
|
||||||
|
offers.sort((a, b) => a.total - b.total);
|
||||||
|
|
||||||
|
const details = offers[0].want.data;
|
||||||
|
|
||||||
|
return {
|
||||||
|
details,
|
||||||
|
offers,
|
||||||
|
status,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function samples() {
|
||||||
|
const user = await pg.userFindEmail('ntr@mnml.gg');
|
||||||
|
const offerGroups = await userOffers(user);
|
||||||
|
const i = Math.floor(Math.random() * offerGroups.length / 2);
|
||||||
|
return offerGroups[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
generate,
|
||||||
|
accept,
|
||||||
|
statusSet,
|
||||||
|
acpOffers,
|
||||||
|
userOffers,
|
||||||
|
samples,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Offers = ReturnType<typeof createOffers>;
|
||||||
@@ -32,6 +32,8 @@ function Main({ wants, offers }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(offers)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<nav>
|
<nav>
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { defineConfig } from "$fresh/server.ts";
|
import { defineConfig } from "$fresh/server.ts";
|
||||||
// import twind from "$fresh/plugins/twindv1.ts";
|
// import twind from "$fresh/plugins/twindv1.ts";
|
||||||
// import twindConfig from "./twind.config.ts";
|
// import twindConfig from "./twind.config.ts";
|
||||||
import { authMiddleware } from "api/auth.middleware.ts";
|
|
||||||
import { errorMiddleware } from "api/error.middleware.ts";
|
|
||||||
import lessPlugin from "./less.plugin.ts";
|
import lessPlugin from "./less.plugin.ts";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -10,8 +8,4 @@ export default defineConfig({
|
|||||||
// twind(twindConfig),
|
// twind(twindConfig),
|
||||||
lessPlugin()
|
lessPlugin()
|
||||||
],
|
],
|
||||||
middleware: {
|
|
||||||
auth: authMiddleware,
|
|
||||||
error: errorMiddleware,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
+2
-2
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import * as $_404 from './routes/_404.tsx'
|
import * as $_404 from './routes/_404.tsx'
|
||||||
import * as $_app from './routes/_app.tsx'
|
import * as $_app from './routes/_app.tsx'
|
||||||
|
import * as $_middleware from './routes/_middleware.ts'
|
||||||
import * as $api_auth_login from './routes/api/auth/login.ts'
|
import * as $api_auth_login from './routes/api/auth/login.ts'
|
||||||
import * as $api_auth_logout from './routes/api/auth/logout.ts'
|
import * as $api_auth_logout from './routes/api/auth/logout.ts'
|
||||||
import * as $api_auth_register from './routes/api/auth/register.ts'
|
import * as $api_auth_register from './routes/api/auth/register.ts'
|
||||||
@@ -11,7 +12,6 @@ import * as $api_auth_status from './routes/api/auth/status.ts'
|
|||||||
import * as $api_offers from './routes/api/offers.ts'
|
import * as $api_offers from './routes/api/offers.ts'
|
||||||
import * as $api_wants from './routes/api/wants.ts'
|
import * as $api_wants from './routes/api/wants.ts'
|
||||||
import * as $home from './routes/home.tsx'
|
import * as $home from './routes/home.tsx'
|
||||||
import * as $index from './routes/index.tsx'
|
|
||||||
import * as $login from './routes/login.tsx'
|
import * as $login from './routes/login.tsx'
|
||||||
import * as $register from './routes/register.tsx'
|
import * as $register from './routes/register.tsx'
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@ const manifest = {
|
|||||||
routes: {
|
routes: {
|
||||||
'./routes/_404.tsx': $_404,
|
'./routes/_404.tsx': $_404,
|
||||||
'./routes/_app.tsx': $_app,
|
'./routes/_app.tsx': $_app,
|
||||||
|
'./routes/_middleware.ts': $_middleware,
|
||||||
'./routes/api/auth/login.ts': $api_auth_login,
|
'./routes/api/auth/login.ts': $api_auth_login,
|
||||||
'./routes/api/auth/logout.ts': $api_auth_logout,
|
'./routes/api/auth/logout.ts': $api_auth_logout,
|
||||||
'./routes/api/auth/register.ts': $api_auth_register,
|
'./routes/api/auth/register.ts': $api_auth_register,
|
||||||
@@ -28,7 +29,6 @@ const manifest = {
|
|||||||
'./routes/api/offers.ts': $api_offers,
|
'./routes/api/offers.ts': $api_offers,
|
||||||
'./routes/api/wants.ts': $api_wants,
|
'./routes/api/wants.ts': $api_wants,
|
||||||
'./routes/home.tsx': $home,
|
'./routes/home.tsx': $home,
|
||||||
'./routes/index.tsx': $index,
|
|
||||||
'./routes/login.tsx': $login,
|
'./routes/login.tsx': $login,
|
||||||
'./routes/register.tsx': $register,
|
'./routes/register.tsx': $register,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
import { FreshContext } from "$fresh/server.ts";
|
import { FreshContext } from "$fresh/server.ts";
|
||||||
import { Pg } from 'api/pg.ts'
|
import { Pg } from 'api/pg.ts'
|
||||||
import { User } from 'prisma/generated/index.d.ts'
|
import { User } from 'prisma/generated/index.ts'
|
||||||
|
import { authMiddleware } from 'api/auth.middleware.ts'
|
||||||
|
import { errorMiddleware } from 'api/error.middleware.ts'
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
pg: Pg;
|
pg: Pg;
|
||||||
user: User
|
user: User
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handler(
|
export const handler = [errorMiddleware, authMiddleware]
|
||||||
req: Request,
|
|
||||||
ctx: FreshContext<State>,
|
|
||||||
) {
|
|
||||||
ctx.state.data = "myData";
|
|
||||||
const resp = await ctx.next();
|
|
||||||
resp.headers.set("server", "fresh server");
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
import { Handlers } from "$fresh/server.ts"
|
import { Handlers } from "$fresh/server.ts"
|
||||||
import { createPg } from "../../api/pg.ts"
|
|
||||||
|
|
||||||
export const handler: Handlers = {
|
export const handler: Handlers = {
|
||||||
async GET(_req, ctx) {
|
async GET(_req, ctx) {
|
||||||
const user = ctx.state.user
|
const user = ctx.state.user
|
||||||
const pg = createPg(console)
|
|
||||||
const offers = await pg.userOffers(user)
|
const offers = await pg.userOffers(user)
|
||||||
|
|
||||||
return new Response(JSON.stringify(offers), {
|
return new Response(JSON.stringify(offers), {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||||
import { createPg, Pg } from "../api/pg.ts";
|
import { createPg, Pg } from "../api/pg.ts";
|
||||||
import Main from "../components/main.tsx";
|
import Main from "../components/main.tsx";
|
||||||
import { User } from 'prisma/generated/index.d.ts'
|
import { User } from 'prisma/generated/index.ts'
|
||||||
|
|
||||||
export const handler: Handlers = {
|
export const handler: Handlers = {
|
||||||
async GET(req, ctx) {
|
async GET(req, ctx) {
|
||||||
|
|||||||
Reference in new issue
Block a user