ag-common 0.0.88 → 0.0.92
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/dist/api/helpers/openApiHelpers.d.ts +2 -2
- package/dist/api/helpers/openApiHelpers.js +10 -8
- package/dist/api/helpers/validations.d.ts +5 -1
- package/dist/api/helpers/validations.js +25 -15
- package/dist/api/types/index.d.ts +6 -5
- package/dist/ui/helpers/cognito.d.ts +0 -18
- package/dist/ui/helpers/routes.d.ts +1 -5
- package/package.json +1 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { aws_certificatemanager as certmgr, aws_route53 as route53 } from 'aws-cdk-lib';
|
|
2
2
|
import { Construct } from 'constructs';
|
|
3
|
-
import {
|
|
3
|
+
import { ILambdaConfigs } from '../types';
|
|
4
4
|
export declare const openApiImpl: (p: {
|
|
5
5
|
schema: any;
|
|
6
6
|
stack: Construct;
|
|
7
7
|
NODE_ENV: string;
|
|
8
8
|
baseUrl: string;
|
|
9
9
|
endpointsBase: string;
|
|
10
|
-
|
|
10
|
+
lambdaConfig: ILambdaConfigs;
|
|
11
11
|
certificate: certmgr.ICertificate;
|
|
12
12
|
hostedZone: route53.IHostedZone;
|
|
13
13
|
shortStackName: string;
|
|
@@ -34,17 +34,17 @@ const setUpApiGw = ({ stack, NODE_ENV, baseUrl, certificate, hostedZone, shortSt
|
|
|
34
34
|
});
|
|
35
35
|
return api;
|
|
36
36
|
};
|
|
37
|
-
const setupLambda = ({
|
|
37
|
+
const setupLambda = ({ lambdaConfig, pathV, verb, seenPermissions, }) => {
|
|
38
38
|
var _a, _b, _c, _d;
|
|
39
39
|
const pathCompute = pathV + '/' + verb;
|
|
40
|
-
const lp =
|
|
40
|
+
const lp = lambdaConfig === null || lambdaConfig === void 0 ? void 0 : lambdaConfig[pathCompute];
|
|
41
41
|
if (lp) {
|
|
42
42
|
seenPermissions[pathCompute] = true;
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
45
|
seenPermissions[pathCompute] = false;
|
|
46
46
|
}
|
|
47
|
-
const def =
|
|
47
|
+
const def = lambdaConfig === null || lambdaConfig === void 0 ? void 0 : lambdaConfig.default;
|
|
48
48
|
if (def) {
|
|
49
49
|
seenPermissions.default = true;
|
|
50
50
|
}
|
|
@@ -52,13 +52,14 @@ const setupLambda = ({ lambdaPermissions, pathV, verb, seenPermissions, }) => {
|
|
|
52
52
|
const readTables = (0, distinctBy_1.distinctBy)([...(((_a = def === null || def === void 0 ? void 0 : def.dynamo) === null || _a === void 0 ? void 0 : _a.reads) || []), ...(((_b = lp === null || lp === void 0 ? void 0 : lp.dynamo) === null || _b === void 0 ? void 0 : _b.reads) || [])], (s) => s.shortName);
|
|
53
53
|
const writeTables = (0, distinctBy_1.distinctBy)([...(((_c = def === null || def === void 0 ? void 0 : def.dynamo) === null || _c === void 0 ? void 0 : _c.writes) || []), ...(((_d = lp === null || lp === void 0 ? void 0 : lp.dynamo) === null || _d === void 0 ? void 0 : _d.writes) || [])], (s) => s.shortName);
|
|
54
54
|
const policies = [...(def.policies || []), ...((lp === null || lp === void 0 ? void 0 : lp.policies) || [])].filter(__1.notEmpty);
|
|
55
|
+
const layers = [...(def.layers || []), ...((lp === null || lp === void 0 ? void 0 : lp.layers) || [])].filter(__1.notEmpty);
|
|
55
56
|
const env = Object.assign(Object.assign({}, (def.env || {})), ((lp === null || lp === void 0 ? void 0 : lp.env) || {}));
|
|
56
57
|
const tables = [...readTables, ...writeTables];
|
|
57
58
|
const environment = env;
|
|
58
59
|
Object.values(tables).forEach((v) => {
|
|
59
60
|
environment[v.shortName] = v.table.tableName;
|
|
60
61
|
});
|
|
61
|
-
return { environment, readTables, writeTables, policies };
|
|
62
|
+
return { environment, readTables, writeTables, policies, layers };
|
|
62
63
|
};
|
|
63
64
|
const addApiPaths = (api, pathList, apiRoots) => {
|
|
64
65
|
let pathBuild = '';
|
|
@@ -83,7 +84,7 @@ const openApiImpl = (p) => {
|
|
|
83
84
|
if (!p.schema) {
|
|
84
85
|
throw new Error('no openapi schema found');
|
|
85
86
|
}
|
|
86
|
-
const { stack, NODE_ENV, endpointsBase,
|
|
87
|
+
const { stack, NODE_ENV, endpointsBase, lambdaConfig } = p;
|
|
87
88
|
const paths = getPaths(p.schema);
|
|
88
89
|
const api = setUpApiGw(p);
|
|
89
90
|
const apiRoots = {};
|
|
@@ -91,8 +92,8 @@ const openApiImpl = (p) => {
|
|
|
91
92
|
paths.forEach(({ fullPath, verbs, pathList }) => {
|
|
92
93
|
const apiPath = addApiPaths(api, pathList, apiRoots);
|
|
93
94
|
verbs.forEach((verb) => {
|
|
94
|
-
const { environment, readTables, writeTables, policies } = setupLambda({
|
|
95
|
-
|
|
95
|
+
const { environment, readTables, writeTables, policies, layers } = setupLambda({
|
|
96
|
+
lambdaConfig,
|
|
96
97
|
pathV: fullPath,
|
|
97
98
|
verb,
|
|
98
99
|
seenPermissions,
|
|
@@ -113,6 +114,7 @@ const openApiImpl = (p) => {
|
|
|
113
114
|
},
|
|
114
115
|
reservedConcurrentExecutions: 5,
|
|
115
116
|
logRetention: aws_cdk_lib_1.aws_logs.RetentionDays.FIVE_DAYS,
|
|
117
|
+
layers,
|
|
116
118
|
});
|
|
117
119
|
readTables.forEach((t) => t.table.grantReadData(lambdaV));
|
|
118
120
|
writeTables.forEach((t) => t.table.grantReadWriteData(lambdaV));
|
|
@@ -121,7 +123,7 @@ const openApiImpl = (p) => {
|
|
|
121
123
|
apiPath.addMethod(verb.toUpperCase(), new aws_cdk_lib_1.aws_apigateway.LambdaIntegration(lambdaV, {}));
|
|
122
124
|
});
|
|
123
125
|
});
|
|
124
|
-
Object.keys(
|
|
126
|
+
Object.keys(lambdaConfig).forEach((k) => {
|
|
125
127
|
if (!seenPermissions[k] || seenPermissions[k] === false) {
|
|
126
128
|
(0, log_1.warn)(`unused permissions for '${k}', did you mean one of these paths?=`, Object.entries(seenPermissions)
|
|
127
129
|
.filter(([, b]) => !b)
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { error } from '../../common/helpers/log';
|
|
2
2
|
import { User } from '../../ui/helpers/jwt';
|
|
3
3
|
import { APIGatewayProxyResult } from '../types';
|
|
4
|
-
export declare const getAndValidateToken: ({ tokenRaw, COGNITO_USER_POOL_ID, }: {
|
|
4
|
+
export declare const getAndValidateToken: ({ tokenRaw, jwksRegion, COGNITO_USER_POOL_ID, }: {
|
|
5
|
+
/**
|
|
6
|
+
* default ap-southeast-2
|
|
7
|
+
*/
|
|
8
|
+
jwksRegion?: string | undefined;
|
|
5
9
|
tokenRaw?: string | undefined;
|
|
6
10
|
COGNITO_USER_POOL_ID: string;
|
|
7
11
|
}) => Promise<{
|
|
@@ -19,9 +19,7 @@ const jsonwebtoken_1 = require("jsonwebtoken");
|
|
|
19
19
|
const log_1 = require("../../common/helpers/log");
|
|
20
20
|
const api_1 = require("./api");
|
|
21
21
|
let jwksClient;
|
|
22
|
-
const jwtVerify = ({
|
|
23
|
-
const jwksUri = `https://cognito-idp.ap-southeast-2.amazonaws.com/${COGNITO_USER_POOL_ID}/.well-known/jwks.json`;
|
|
24
|
-
const issuer = `https://cognito-idp.ap-southeast-2.amazonaws.com/${COGNITO_USER_POOL_ID}`;
|
|
22
|
+
const jwtVerify = ({ token, jwksUri, issuer, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
23
|
return new Promise((resolve, reject) => {
|
|
26
24
|
(0, jsonwebtoken_1.verify)(token, (header, callback) => {
|
|
27
25
|
if (!jwksClient) {
|
|
@@ -60,22 +58,39 @@ const jwtVerify = ({ COGNITO_USER_POOL_ID, token, }) => __awaiter(void 0, void 0
|
|
|
60
58
|
});
|
|
61
59
|
});
|
|
62
60
|
});
|
|
63
|
-
const getAndValidateToken = ({ tokenRaw, COGNITO_USER_POOL_ID, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
|
+
const getAndValidateToken = ({ tokenRaw, jwksRegion = 'ap-southeast-2', COGNITO_USER_POOL_ID, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
62
|
var _a, _b;
|
|
63
|
+
const jwksUri = `https://cognito-idp.${jwksRegion}.amazonaws.com/${COGNITO_USER_POOL_ID}/.well-known/jwks.json`;
|
|
64
|
+
const issuer = `https://cognito-idp.${jwksRegion}.amazonaws.com/${COGNITO_USER_POOL_ID}`;
|
|
65
65
|
let token = '';
|
|
66
66
|
try {
|
|
67
67
|
if (!tokenRaw) {
|
|
68
|
-
|
|
68
|
+
const m = 'no auth headers, auth failed';
|
|
69
|
+
(0, log_1.error)(m);
|
|
69
70
|
return {
|
|
70
|
-
error: (0, api_1.returnCode)(403,
|
|
71
|
+
error: (0, api_1.returnCode)(403, m),
|
|
71
72
|
};
|
|
72
73
|
}
|
|
73
74
|
token = tokenRaw.substring(tokenRaw.indexOf(' ') + 1);
|
|
75
|
+
if (!token) {
|
|
76
|
+
const m = 'auth error: no token';
|
|
77
|
+
(0, log_1.error)(m);
|
|
78
|
+
return {
|
|
79
|
+
error: (0, api_1.returnCode)(403, m),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
74
82
|
let subject;
|
|
75
83
|
try {
|
|
76
|
-
yield jwtVerify({ token,
|
|
84
|
+
yield jwtVerify({ token, jwksUri, issuer });
|
|
77
85
|
const decoded = (0, jsonwebtoken_1.decode)(token);
|
|
78
86
|
(0, log_1.debug)(`decoded=${JSON.stringify(decoded, null, 2)}`);
|
|
87
|
+
if (!decoded.email) {
|
|
88
|
+
const m = 'auth error, no email';
|
|
89
|
+
(0, log_1.error)(m);
|
|
90
|
+
return {
|
|
91
|
+
error: (0, api_1.returnCode)(403, m),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
79
94
|
subject = decoded === null || decoded === void 0 ? void 0 : decoded.sub;
|
|
80
95
|
if (!subject) {
|
|
81
96
|
const mess = 'user should have responded with subject (sub) field';
|
|
@@ -96,12 +111,6 @@ const getAndValidateToken = ({ tokenRaw, COGNITO_USER_POOL_ID, }) => __awaiter(v
|
|
|
96
111
|
picture,
|
|
97
112
|
updatedAt: parseInt(`${decoded.auth_time}000`, 10),
|
|
98
113
|
};
|
|
99
|
-
if (!userProfile || !token || !userProfile.userId) {
|
|
100
|
-
(0, log_1.error)('auth fail');
|
|
101
|
-
return {
|
|
102
|
-
error: (0, api_1.returnCode)(403, 'auth fail'),
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
114
|
return { token, userProfile };
|
|
106
115
|
}
|
|
107
116
|
catch (e) {
|
|
@@ -114,9 +123,10 @@ const getAndValidateToken = ({ tokenRaw, COGNITO_USER_POOL_ID, }) => __awaiter(v
|
|
|
114
123
|
}
|
|
115
124
|
}
|
|
116
125
|
catch (e) {
|
|
117
|
-
|
|
126
|
+
const m = 'auth error:' + JSON.stringify(e, null, 2);
|
|
127
|
+
(0, log_1.error)(m);
|
|
118
128
|
return {
|
|
119
|
-
error: (0, api_1.returnCode)(403,
|
|
129
|
+
error: (0, api_1.returnCode)(403, m),
|
|
120
130
|
};
|
|
121
131
|
}
|
|
122
132
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { aws_dynamodb as dynamodb, aws_iam as iam } from 'aws-cdk-lib';
|
|
1
|
+
import { aws_dynamodb as dynamodb, aws_iam as iam, aws_lambda as lambda } from 'aws-cdk-lib';
|
|
2
2
|
import { Key } from './aws';
|
|
3
3
|
export interface DYNAMOKEYS {
|
|
4
4
|
type: string;
|
|
@@ -17,17 +17,18 @@ export interface IGeneratedDynamoData {
|
|
|
17
17
|
table: dynamodb.ITable;
|
|
18
18
|
shortName: string;
|
|
19
19
|
}
|
|
20
|
-
export interface
|
|
20
|
+
export interface ILambdaConfig {
|
|
21
21
|
dynamo?: {
|
|
22
22
|
reads?: IGeneratedDynamoData[];
|
|
23
23
|
writes?: IGeneratedDynamoData[];
|
|
24
24
|
};
|
|
25
25
|
policies?: iam.PolicyStatement[];
|
|
26
26
|
env?: Record<string, string>;
|
|
27
|
+
layers?: lambda.ILayerVersion[];
|
|
27
28
|
}
|
|
28
|
-
export interface
|
|
29
|
-
[pathHyphenVerb: string]:
|
|
30
|
-
default?:
|
|
29
|
+
export interface ILambdaConfigs {
|
|
30
|
+
[pathHyphenVerb: string]: ILambdaConfig & {
|
|
31
|
+
default?: ILambdaConfig;
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
export interface IQueryDynamo {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
export declare type TOnMessage = (m: string, options?: {
|
|
3
2
|
appearance: 'error' | 'success';
|
|
4
3
|
}) => void;
|
|
@@ -12,20 +11,3 @@ export interface ICognitoAuth {
|
|
|
12
11
|
cognitoRefresh: string;
|
|
13
12
|
vendToken: string;
|
|
14
13
|
}
|
|
15
|
-
export interface ICognitoAuthProviderProps {
|
|
16
|
-
redirectUrl?: string;
|
|
17
|
-
location: {
|
|
18
|
-
pathname: string;
|
|
19
|
-
hash: string;
|
|
20
|
-
search: string;
|
|
21
|
-
origin: string;
|
|
22
|
-
};
|
|
23
|
-
goToPageUrl: ({ url, state, login, }: {
|
|
24
|
-
url: string;
|
|
25
|
-
state?: any;
|
|
26
|
-
login: boolean;
|
|
27
|
-
}) => Promise<void>;
|
|
28
|
-
children: JSX.Element | JSX.Element[];
|
|
29
|
-
config: ICognitoAuth;
|
|
30
|
-
onMessage?: TOnMessage;
|
|
31
|
-
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { TLang } from '../..';
|
|
3
|
-
import { ICognitoAuth
|
|
4
|
-
import { AuthedUserContext } from './jwt';
|
|
2
|
+
import { ICognitoAuth } from './cognito';
|
|
5
3
|
export interface LocationSubset {
|
|
6
4
|
pathname: string;
|
|
7
5
|
hash: string;
|
|
@@ -30,7 +28,5 @@ export interface IRequestCommon {
|
|
|
30
28
|
export interface IStateCommon<TRequest extends IRequestCommon> extends IInitialStateCommon {
|
|
31
29
|
request: TRequest;
|
|
32
30
|
auth: ICognitoAuth;
|
|
33
|
-
CognitoAuthContext: React.Context<AuthedUserContext>;
|
|
34
|
-
CognitoAuthProvider: (p: ICognitoAuthProviderProps) => JSX.Element;
|
|
35
31
|
pushPath: (path: string) => Promise<void>;
|
|
36
32
|
}
|