@sustaina/iam-middleware
v1.3.1
Published
``` npm install @sustaina/iam-middleware ```
Downloads
874
Readme
@sustaina/iam-middleware
Installation
npm install @sustaina/iam-middlewareENV
If you don't provide redisUrl/redisInstance or jwtSecret directly in a class constructor, you can provide these by env including:
IAM_REDIS_URL and IAM_JWT_SECRET
For CD
add these line in kustomization.yaml file in *-deploy repository
patch: |-
- op: add
path: ...
value:
- secretRef:
name: your-secret
- secretRef:
name: iam-middleware-dev-secret # <--- add this
# change dev to -> sit / uatnow you're good to go.
Information Attached to Request Object
This package extends FastifyRequest interface to include user property and jwt payload.
you can get tenantId from request.payload?.tenantId.
declare module "fastify" {
interface FastifyRequest {
user?: UserInfo;
payload?: JwtPayload;
isAuthenticated?: boolean;
admin?: AdminInfo;
adminPayload?: AdminJwtPayload;
isAuthenticatedAdmin?: boolean;
}
}
export interface UserInfo {
id: string;
name: string;
email: string;
type: string;
}
export interface AdminJwtPayload {
id: string;
name: string;
email: string;
isPlatformAdmin: true;
}
export interface JwtPayload {
id: string;
name: string;
email: string;
tenantId: string;
type: string;
tenantLocale: string;
passwordPolicy: string;
isDenyPasswordChange: boolean;
isPasswordSendEmail: boolean;
}
export interface AdminInfo {
id: string;
name: string;
email: string;
}Available Method
const authMiddleware = new AuthMiddleware();
const implementMode = new ImplementModeMiddleware();
authMiddleware.authenticate
authMiddleware.optionalAuthenticate // don't abort and don't return 401
authMiddleware.authenticateAdmin
authMiddleware.optionalAuthenticateAdmin // don't abort and don't return 401
authMiddleware.authenticateAll // return 401 if both user and admin authentication fail
authMiddleware.permissionGuard([{ access: "canRead", subProgram: "test" }]);
implementMode.authoriseExample Usage
import "dotenv/config";
import fastify from "fastify";
import pino from "pino";
import { AuthMiddleware, ImplementModeMiddleware } from "@sustaina/iam-middleware";
const logger = pino({
level: process.env.LOG_LEVEL || "info",
transport: { target: "pino-pretty", options: { colorize: true } },
});
async function createApp() {
const app = fastify();
const authMiddleware = new AuthMiddleware();
const implementMode = new ImplementModeMiddleware();
// Register middlewares to GROUP OF routes
await app.register(
async (appInstance) => {
appInstance.addHook("preHandler", authMiddleware.authenticate.bind(authMiddleware)); // required for implementMode.authorise and authMiddleware.
appInstance.addHook("preHandler", implementMode.authorise.bind(implementMode));
appInstance.addHook("preHandler", authMiddleware.permissionGuard([{ access: "canRead", subProgram: "test" }]).bind(authMiddleware));
appInstance.get("/test", {}, async (request, reply) => {
return reply.send({
success: true,
});
});
appInstance.get("/test2", {}, async (request, reply) => {
return reply.send({
success: false,
});
});
},
{ prefix: "/api/v1" }
);
// Register middlewares to each route
await app.register(
async (appInstance) => {
appInstance.get(
"/test",
{
preHandler: [
authMiddleware.authenticate.bind(authMiddleware), // required for implementMode.authorise and authMiddleware.permissionGuard
implementMode.authorise.bind(implementMode),
authMiddleware.permissionGuard([{ access: "canRead", subProgram: "test" }]).bind(authMiddleware),
],
},
async (request, reply) => {
return reply.send({
success: true,
});
}
);
},
{ prefix: "/api/v1" }
);
return app;
}
