@eduzz/miau-client 1.2.0 → 1.2.1

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.0 build:types /home/runner/work/eduzz-miau/eduzz-miau/packages/client
2
+ > @eduzz/miau-client@1.2.1 build:types /home/runner/work/eduzz-miau/eduzz-miau/packages/client
3
3
  > tsc --emitDeclarationOnly --outDir dist
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { type RequestHandler } from 'express';
2
- import { type SecretEnv, type Permission, type Resource } from '@eduzz/miau-types';
2
+ import { type SecretEnv, type Permission, type Resource, type MiauClientToken } from '@eduzz/miau-types';
3
3
  import { type RequestAugmentation } from './middleware';
4
4
  type MiauClientConfig = {
5
5
  apiUrl: string;
@@ -14,12 +14,14 @@ export declare class MiauClient {
14
14
  getEnvironment(): SecretEnv;
15
15
  getPublicKey(kid: string): Promise<string>;
16
16
  getToken(): Promise<string | undefined>;
17
+ getTokenData: () => Promise<MiauClientToken>;
17
18
  middleware<T = Record<string, string>>(config?: {
18
19
  requestAugmentation?: RequestAugmentation<T>;
19
20
  fallbackMiddleware?: RequestHandler;
20
21
  }): RequestHandler;
21
22
  getResources(): Promise<Resource[]>;
22
23
  getPermissions(targetAppId: string): Promise<Permission>;
24
+ verify(token: string, publicKey: string): Promise<MiauClientToken>;
23
25
  private getApiJwtUrl;
24
26
  private getPermissionsUrl;
25
27
  private getResourcesUrl;
package/dist/index.js CHANGED
@@ -11909,8 +11909,8 @@ var isResourceAllowed = (resource, resources, permittedResources) => {
11909
11909
 
11910
11910
  // src/middleware.ts
11911
11911
  var HttpError = class _HttpError extends Error {
11912
- constructor(status, name, message) {
11913
- super(message);
11912
+ constructor(status, name, message, code) {
11913
+ super(`${message} (${code})`);
11914
11914
  this.name = name;
11915
11915
  this.status = status;
11916
11916
  Object.setPrototypeOf(this, _HttpError.prototype);
@@ -11921,49 +11921,59 @@ var miauMiddleware = (miauClient, requestAugmentation, fallbackMiddleware) => {
11921
11921
  try {
11922
11922
  const token = req.headers.authorization?.split(" ").pop();
11923
11923
  if (!token) {
11924
- throw new HttpError(400, "Invalid Token", "Token not provided");
11924
+ throw new HttpError(400, "Invalid Token", "Token not provided", "MIAU_TKN_A");
11925
11925
  }
11926
11926
  const decodedToken = import_jsonwebtoken.default.decode(token, { complete: true });
11927
11927
  if (!decodedToken) {
11928
- throw new HttpError(400, "Invalid Token", "Token could not be decoded");
11928
+ throw new HttpError(400, "Invalid Token", "Token could not be decoded", "MIAU_TKN_B");
11929
11929
  }
11930
11930
  if (!decodedToken.header?.kid) {
11931
- throw new HttpError(400, "Invalid Token", "Missing kid in token header");
11931
+ throw new HttpError(400, "Invalid Token", "Missing kid in token header", "MIAU_TKN_C");
11932
11932
  }
11933
11933
  if (decodedToken.payload.iss !== issuers["production"]) {
11934
- throw new HttpError(400, "Invalid Token", "Token issuer is invalid");
11934
+ throw new HttpError(400, "Invalid Token", "Token issuer is invalid", "MIAU_TKN_D");
11935
11935
  }
11936
11936
  const publicKey = await miauClient.getPublicKey(decodedToken.header.kid);
11937
- const clientToken = import_jsonwebtoken.default.verify(token, publicKey, { algorithms: ["RS256"] });
11938
- if (!clientToken || !clientToken.application || !clientToken.secret || !clientToken.application.id || !clientToken.secret.id || !clientToken.secret.environment) {
11939
- throw new HttpError(400, "Invalid Token", "Token verification failed");
11940
- }
11941
- const { application, secret } = clientToken;
11942
- if (secret.environment != miauClient.getEnvironment()) {
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) {
11943
11945
  throw new HttpError(
11944
- 400,
11946
+ 401,
11945
11947
  "Invalid Environment",
11946
- `Secret environment ${secret.environment} does not match client environment ${miauClient.getEnvironment()}`
11948
+ `Secret environment ${clientSecret.environment} does not match Server environment ${serverSecret.environment}`,
11949
+ "MIAU_ENV_A"
11947
11950
  );
11948
11951
  }
11949
11952
  const resources = await miauClient.getResources();
11950
11953
  if (!resources) {
11951
- throw new HttpError(401, "Unauthorized", "No resources found for this application");
11954
+ throw new HttpError(401, "Unauthorized", `No resources configured in ${serverApplication.name}`, "MIAU_RES_A");
11952
11955
  }
11953
- const permission = await miauClient.getPermissions(application.id);
11956
+ const permission = await miauClient.getPermissions(clientApplication.id);
11954
11957
  if (!permission) {
11955
- throw new HttpError(401, "Unauthorized", "No permissions found for this application");
11958
+ throw new HttpError(
11959
+ 401,
11960
+ "Unauthorized",
11961
+ `No permissions found for ${clientApplication.name} in ${serverApplication.name}`,
11962
+ "MIAU_PERM_A"
11963
+ );
11956
11964
  }
11957
11965
  const permittedResources = permission?.resources || [];
11958
- if (!permittedResources.length) {
11959
- throw new HttpError(403, "Forbidden", "No resources are permitted for this application");
11960
- }
11961
11966
  const resource = { protocol: "http", method: req.method, path: req.path };
11962
11967
  const isAllowed = isResourceAllowed(resource, resources, permittedResources);
11963
11968
  if (!isAllowed) {
11964
- throw new HttpError(403, "Forbidden", `You do not have permission to access ${req.method} ${req.path}`);
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
+ );
11965
11975
  }
11966
- req.miauApplication = { id: application.id, name: application.name };
11976
+ req.miauApplication = { id: clientApplication.id, name: clientApplication.name };
11967
11977
  const environment = miauClient.getEnvironment();
11968
11978
  req.miauMetadata = permission?.metadata?.[environment] || {};
11969
11979
  if (requestAugmentation) {
@@ -12022,6 +12032,13 @@ var expiresHeaderToUnixtime = (expires) => {
12022
12032
  };
12023
12033
  var MiauClient = class {
12024
12034
  constructor(config) {
12035
+ this.getTokenData = async () => {
12036
+ const token = await this.getToken();
12037
+ if (!token) {
12038
+ throw new Error("Token is undefined");
12039
+ }
12040
+ return import_jsonwebtoken2.default.decode(token);
12041
+ };
12025
12042
  this.getApiJwtUrl = () => {
12026
12043
  return `${this.config.apiUrl}/v1/jwt`;
12027
12044
  };
@@ -12091,6 +12108,9 @@ var MiauClient = class {
12091
12108
  headers: { Authorization: `Basic ${this.basicAuthToken}` }
12092
12109
  });
12093
12110
  }
12111
+ async verify(token, publicKey) {
12112
+ return import_jsonwebtoken2.default.verify(token, publicKey, { algorithms: ["RS256"] });
12113
+ }
12094
12114
  };
12095
12115
  // Annotate the CommonJS export names for ESM import in node:
12096
12116
  0 && (module.exports = {