@eduzz/miau-client 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
 
2
- > @eduzz/miau-client@1.2.1 build:types /home/runner/work/eduzz-miau/eduzz-miau/packages/client
2
+ > @eduzz/miau-client@1.3.0 build:types /home/runner/work/eduzz-miau/eduzz-miau/packages/client
3
3
  > tsc --emitDeclarationOnly --outDir dist
4
4
 
@@ -1,4 +1,5 @@
1
- import { type RequestHandler } from 'express';
1
+ import { type Request, type RequestHandler } from 'express';
2
+ import { type FastifyReply, type FastifyRequest } from 'fastify';
2
3
  import { type SecretEnv, type Permission, type Resource, type MiauClientToken } from '@eduzz/miau-types';
3
4
  import { type RequestAugmentation } from './middleware';
4
5
  type MiauClientConfig = {
@@ -16,9 +17,13 @@ export declare class MiauClient {
16
17
  getToken(): Promise<string | undefined>;
17
18
  getTokenData: () => Promise<MiauClientToken>;
18
19
  middleware<T = Record<string, string>>(config?: {
19
- requestAugmentation?: RequestAugmentation<T>;
20
+ requestAugmentation?: RequestAugmentation<T, Request>;
20
21
  fallbackMiddleware?: RequestHandler;
21
22
  }): RequestHandler;
23
+ hook<T = Record<string, string>>(config?: {
24
+ requestAugmentation?: RequestAugmentation<T, FastifyRequest>;
25
+ fallbackMiddleware?: (request: FastifyRequest, reply: FastifyReply) => void;
26
+ }): (request: FastifyRequest, reply: FastifyReply) => void;
22
27
  getResources(): Promise<Resource[]>;
23
28
  getPermissions(targetAppId: string): Promise<Permission>;
24
29
  verify(token: string, publicKey: string): Promise<MiauClientToken>;
package/dist/index.js CHANGED
@@ -11816,9 +11816,7 @@ var expirationOptions = {
11816
11816
  "Twelve hours": "twelveHours",
11817
11817
  "One day": "oneDay",
11818
11818
  "One week": "sevenDays",
11819
- "One month": "oneMonth",
11820
- "Six months": "sixMonths",
11821
- "One year": "oneYear"
11819
+ "One month": "oneMonth"
11822
11820
  };
11823
11821
  var expirationOptionsValues = Object.values(expirationOptions);
11824
11822
  var conversionMap = {
@@ -11916,66 +11914,72 @@ var HttpError = class _HttpError extends Error {
11916
11914
  Object.setPrototypeOf(this, _HttpError.prototype);
11917
11915
  }
11918
11916
  };
11917
+ var auth = async (token, method, path, miauClient) => {
11918
+ if (!token) {
11919
+ throw new HttpError(400, "Invalid Token", "Token not provided", "MIAU_TKN_A");
11920
+ }
11921
+ const decodedToken = import_jsonwebtoken.default.decode(token, { complete: true });
11922
+ if (!decodedToken) {
11923
+ throw new HttpError(400, "Invalid Token", "Token could not be decoded", "MIAU_TKN_B");
11924
+ }
11925
+ if (!decodedToken.header?.kid) {
11926
+ throw new HttpError(400, "Invalid Token", "Missing kid in token header", "MIAU_TKN_C");
11927
+ }
11928
+ if (decodedToken.payload.iss !== issuers["production"]) {
11929
+ throw new HttpError(400, "Invalid Token", "Token issuer is invalid", "MIAU_TKN_D");
11930
+ }
11931
+ const publicKey = await miauClient.getPublicKey(decodedToken.header.kid);
11932
+ const clientTokenData = await miauClient.verify(token, publicKey);
11933
+ const serverTokenData = await miauClient.getTokenData();
11934
+ if (!clientTokenData || !clientTokenData.application || !clientTokenData.secret || !clientTokenData.application.id || !clientTokenData.secret.id || !clientTokenData.secret.environment) {
11935
+ throw new HttpError(401, "Invalid Token", "Token invalid or expired", "MIAU_TKN_E");
11936
+ }
11937
+ const { application: clientApplication, secret: clientSecret } = clientTokenData;
11938
+ const { application: serverApplication, secret: serverSecret } = serverTokenData;
11939
+ if (clientSecret.environment != serverSecret.environment) {
11940
+ throw new HttpError(
11941
+ 401,
11942
+ "Invalid Environment",
11943
+ `Secret environment ${clientSecret.environment} does not match Server environment ${serverSecret.environment}`,
11944
+ "MIAU_ENV_A"
11945
+ );
11946
+ }
11947
+ const resources = await miauClient.getResources();
11948
+ if (!resources) {
11949
+ throw new HttpError(401, "Unauthorized", `No resources configured in ${serverApplication.name}`, "MIAU_RES_A");
11950
+ }
11951
+ const permission = await miauClient.getPermissions(clientApplication.id);
11952
+ if (!permission) {
11953
+ throw new HttpError(
11954
+ 401,
11955
+ "Unauthorized",
11956
+ `No permissions found for ${clientApplication.name} in ${serverApplication.name}`,
11957
+ "MIAU_PERM_A"
11958
+ );
11959
+ }
11960
+ const permittedResources = permission?.resources || [];
11961
+ const resource = { protocol: "http", method, path };
11962
+ const isAllowed = isResourceAllowed(resource, resources, permittedResources);
11963
+ if (!isAllowed) {
11964
+ throw new HttpError(
11965
+ 403,
11966
+ "Forbidden",
11967
+ `${clientApplication.name} does not have permission to ${method} ${path} on ${serverApplication.name}`,
11968
+ "MIAU_PERM_B"
11969
+ );
11970
+ }
11971
+ const miauApplication = { id: clientApplication.id, name: clientApplication.name };
11972
+ const environment = miauClient.getEnvironment();
11973
+ const miauMetadata = permission?.metadata?.[environment] || {};
11974
+ return [miauApplication, miauMetadata];
11975
+ };
11919
11976
  var miauMiddleware = (miauClient, requestAugmentation, fallbackMiddleware) => {
11920
11977
  return async (req, res, next) => {
11921
11978
  try {
11922
- const token = req.headers.authorization?.split(" ").pop();
11923
- if (!token) {
11924
- throw new HttpError(400, "Invalid Token", "Token not provided", "MIAU_TKN_A");
11925
- }
11926
- const decodedToken = import_jsonwebtoken.default.decode(token, { complete: true });
11927
- if (!decodedToken) {
11928
- throw new HttpError(400, "Invalid Token", "Token could not be decoded", "MIAU_TKN_B");
11929
- }
11930
- if (!decodedToken.header?.kid) {
11931
- throw new HttpError(400, "Invalid Token", "Missing kid in token header", "MIAU_TKN_C");
11932
- }
11933
- if (decodedToken.payload.iss !== issuers["production"]) {
11934
- throw new HttpError(400, "Invalid Token", "Token issuer is invalid", "MIAU_TKN_D");
11935
- }
11936
- const publicKey = await miauClient.getPublicKey(decodedToken.header.kid);
11937
- const clientTokenData = await miauClient.verify(token, publicKey);
11938
- const serverTokenData = await miauClient.getTokenData();
11939
- if (!clientTokenData || !clientTokenData.application || !clientTokenData.secret || !clientTokenData.application.id || !clientTokenData.secret.id || !clientTokenData.secret.environment) {
11940
- throw new HttpError(401, "Invalid Token", "Token invalid or expired", "MIAU_TKN_E");
11941
- }
11942
- const { application: clientApplication, secret: clientSecret } = clientTokenData;
11943
- const { application: serverApplication, secret: serverSecret } = serverTokenData;
11944
- if (clientSecret.environment != serverSecret.environment) {
11945
- throw new HttpError(
11946
- 401,
11947
- "Invalid Environment",
11948
- `Secret environment ${clientSecret.environment} does not match Server environment ${serverSecret.environment}`,
11949
- "MIAU_ENV_A"
11950
- );
11951
- }
11952
- const resources = await miauClient.getResources();
11953
- if (!resources) {
11954
- throw new HttpError(401, "Unauthorized", `No resources configured in ${serverApplication.name}`, "MIAU_RES_A");
11955
- }
11956
- const permission = await miauClient.getPermissions(clientApplication.id);
11957
- if (!permission) {
11958
- throw new HttpError(
11959
- 401,
11960
- "Unauthorized",
11961
- `No permissions found for ${clientApplication.name} in ${serverApplication.name}`,
11962
- "MIAU_PERM_A"
11963
- );
11964
- }
11965
- const permittedResources = permission?.resources || [];
11966
- const resource = { protocol: "http", method: req.method, path: req.path };
11967
- const isAllowed = isResourceAllowed(resource, resources, permittedResources);
11968
- if (!isAllowed) {
11969
- throw new HttpError(
11970
- 403,
11971
- "Forbidden",
11972
- `${clientApplication.name} does not have permission to ${req.method} ${req.path} on ${serverApplication.name}`,
11973
- "MIAU_PERM_B"
11974
- );
11975
- }
11976
- req.miauApplication = { id: clientApplication.id, name: clientApplication.name };
11977
- const environment = miauClient.getEnvironment();
11978
- req.miauMetadata = permission?.metadata?.[environment] || {};
11979
+ const token = req.headers.authorization?.split(" ").pop() ?? "";
11980
+ const [miauApplication, miauMetadata] = await auth(token, req.method, req.path, miauClient);
11981
+ req.miauApplication = miauApplication;
11982
+ req.miauMetadata = miauMetadata;
11979
11983
  if (requestAugmentation) {
11980
11984
  requestAugmentation({ req, app: req.miauApplication, meta: req.miauMetadata });
11981
11985
  }
@@ -11990,6 +11994,28 @@ var miauMiddleware = (miauClient, requestAugmentation, fallbackMiddleware) => {
11990
11994
  }
11991
11995
  };
11992
11996
  };
11997
+ var miauHook = (miauClient, requestAugmentation, fallbackMiddleware) => {
11998
+ return async (request, reply) => {
11999
+ try {
12000
+ const token = request.headers.authorization?.split(" ").pop() ?? "";
12001
+ const path = request.routeOptions.url ?? "";
12002
+ const [miauApplication, miauMetadata] = await auth(token, request.method, path, miauClient);
12003
+ request.miauApplication = miauApplication;
12004
+ request.miauMetadata = miauMetadata;
12005
+ if (requestAugmentation) {
12006
+ requestAugmentation({ req: request, app: request.miauApplication, meta: request.miauMetadata });
12007
+ }
12008
+ } catch (err) {
12009
+ if (err instanceof HttpError && err.status == 400 && fallbackMiddleware) {
12010
+ await fallbackMiddleware(request, reply);
12011
+ return;
12012
+ }
12013
+ const errorStatus = err.status || 403;
12014
+ reply.status(errorStatus).send({ error: err.name, message: err.message });
12015
+ return;
12016
+ }
12017
+ };
12018
+ };
11993
12019
 
11994
12020
  // src/MiauClient.ts
11995
12021
  var requestsCache = /* @__PURE__ */ new Map();
@@ -12098,6 +12124,9 @@ var MiauClient = class {
12098
12124
  middleware(config) {
12099
12125
  return miauMiddleware(this, config?.requestAugmentation, config?.fallbackMiddleware);
12100
12126
  }
12127
+ hook(config) {
12128
+ return miauHook(this, config?.requestAugmentation, config?.fallbackMiddleware);
12129
+ }
12101
12130
  async getResources() {
12102
12131
  return cacheableFetch(this.getResourcesUrl(), {
12103
12132
  headers: { Authorization: `Basic ${this.basicAuthToken}` }