@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.
- package/.turbo/turbo-build$colon$types.log +1 -1
- package/dist/MiauClient.d.ts +7 -2
- package/dist/index.js +89 -60
- package/dist/index.js.map +2 -2
- package/dist/miau-types/index.js +1 -3
- package/dist/miau-types/index.js.map +2 -2
- package/dist/miau-types/types/Secret.d.ts +6 -4
- package/dist/miau-types/types/Secret.d.ts.map +1 -1
- package/dist/middleware.d.ts +5 -3
- package/package.json +1 -1
- package/src/MiauClient.ts +11 -3
- package/src/middleware.ts +126 -74
- package/src/types/index.d.ts +8 -0
package/dist/MiauClient.d.ts
CHANGED
|
@@ -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
|
-
|
|
11924
|
-
|
|
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}` }
|