add wrappers for using auth in next.js app etc

This commit is contained in:
lingdocs 2022-01-08 12:11:14 +04:00
parent 64883605d1
commit bf1e5cc230
6 changed files with 2130 additions and 104 deletions

2108
account/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,6 @@
"cors": "^2.8.5",
"crypto": "^1.0.1",
"ejs": "^3.1.6",
"express": "^4.17.1",
"express-session": "^1.17.2",
"nano": "^9.0.3",
"node-fetch": "^2.6.1",
@ -47,6 +46,8 @@
"@types/passport-twitter": "^1.0.37",
"@types/redis": "^2.8.31",
"@types/uuid": "^8.3.1",
"express": "^4.17.2",
"next": "^12.0.7",
"ts-node": "^10.1.0",
"typescript": "^4.3.5"
}

View File

@ -0,0 +1,106 @@
import * as AT from "../../../website/src/types/account-types";
import type { Request, Response, NextFunction } from "express";
import type {
NextApiHandler,
GetServerSidePropsContext,
GetServerSidePropsResult,
} from "next";
declare module "http" {
interface IncomingMessage {
user: AT.LingdocsUser | undefined;
}
}
async function fetchUser(cookies: any): Promise<AT.LingdocsUser | undefined> {
if (!cookies) {
return undefined;
}
const cookie = typeof cookies === "string"
? cookies
: `__session=${cookies.__session}`;
try {
const r = await fetch("https://account.lingdocs.com/api/user", { headers: { cookie }});
const { ok, user } = await r.json();
if (ok === true && user) {
return user as AT.LingdocsUser;
}
} catch(e) { console.error(e) }
return undefined;
}
// functions adapted from https://github.com/vvo/iron-session and used similarily, to inculde
// the LingdocsUser in req when signed in
/**
* express middleware to include the LingdocsUser in req.user if signed in
*
* @returns
*/
export async function lingdocsUserExpressMiddleware(req: Request, res: Response, next: NextFunction) {
const user = await fetchUser(req.headers.cookie);
Object.defineProperty(
req,
"user",
{ value: user, writable: false, enumerable: true },
);
next();
}
/**
* wrapper for a next api route to include the LingdocsUser if logged in
*
* Usage:
*
* in next app: pages/api/thing.ts
*
* export default withLingdocsUserApiRoute(
* async function thingRoute(req, res) {
* ...
*
* @param handler
* @returns
*/
export function withLingdocsUserApiRoute(handler: NextApiHandler): NextApiHandler {
return async function nextApiHandlerWrappedWithLingdocsUser(req, res) {
const user = await fetchUser(req.cookies);
Object.defineProperty(
req,
"user",
{ value: user, writable: false, enumerable: true },
);
return handler(req, res);
};
}
/**
* Wrapper for getServer side props to include the LingdocsUser if logged in
*
* usage:
*
* export const getServerSideProps = withLingdocsUserSsr(
* async function getServerSideProps({ req }) {
* ...
*
* @param handler
* @returns
*/
export function withLingdocsUserSsr<
P extends { [key: string]: unknown } = { [key: string]: unknown },
>(
handler: (
context: GetServerSidePropsContext,
) => GetServerSidePropsResult<P> | Promise<GetServerSidePropsResult<P>>) {
return async function nextGetServerSidePropsHandlerWrappedWithLingdocsUser(
context: GetServerSidePropsContext,
) {
const user = await fetchUser(context.req.cookies);
Object.defineProperty(
context.req,
"user",
{ value: user, writable: false, enumerable: true },
);
return handler(context);
};
}

View File

@ -16,6 +16,11 @@ import {
getUser,
postTestResults,
} from "./website/src/lib/backend-calls";
import {
lingdocsUserExpressMiddleware,
withLingdocsUserApiRoute,
withLingdocsUserSsr,
} from "./account/src/lib/with-user";
export {
// FUNCTIONS
@ -30,6 +35,10 @@ export {
updateUserTextOptionsRecord,
getUser,
postTestResults,
// withLingdocsUser functions
lingdocsUserExpressMiddleware,
withLingdocsUserApiRoute,
withLingdocsUserSsr,
// TYPES
AT,
FT,

View File

@ -1,6 +1,6 @@
{
"name": "@lingdocs/lingdocs-main",
"version": "0.2.0",
"version": "0.2.1",
"description": "types and functions for lingdocs stuff",
"main": "dist/library.js",
"module": "dist/library.js",

View File

@ -1821,9 +1821,9 @@
}
},
"@lingdocs/pashto-inflector": {
"version": "1.1.5",
"resolved": "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.1.5.tgz",
"integrity": "sha512-1oMd27IM3oHYn/HnIaG8zwpPXTLNasQigrRZIWzVcg2dyD29gZcapEqaolm72IL20v2UsQxzUrxb8gk+UOF9Cg==",
"version": "1.4.4",
"resolved": "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.4.4.tgz",
"integrity": "sha512-RGf3AZFpy4JWzjWLeeGNLvy1PsDljRcDF4mQIqMPrFeakkuT4h3/exbGAANehNWGt9hm6LbPvXyXQmxe7SWaXg==",
"requires": {
"classnames": "^2.2.6",
"pbf": "^3.2.1",