UNPKG

9.17 kBPlain TextView Raw
1import React, {ReactNode} from 'react';
2
3import Types from '../types';
4import { IComponent} from "../types/component";
5import { IInfrastructure } from "../types";
6import {ENTRY_INSTANCE_TYPE, createEntryProps, IEntryArgs} from "../datalayer/entry-component";
7import { IC_USER_ID} from "./auth-middleware";
8import createMiddleware from '../middleware/middleware-component';
9
10import ConnectSequence from 'connect-sequence';
11
12import {getEntryListQuery, setEntryMutation, setEntry, ddbListEntries, deleteEntry} from '../datalayer/datalayer-libs';
13
14
15import {
16 graphql,
17 GraphQLObjectType,
18 GraphQLString,
19 GraphQLNonNull,
20 GraphQLList,
21 GraphQLInputObjectType
22} from 'graphql';
23
24
25export interface ISecuredEntryProps {
26
27 /**
28 * Functions that the Authentication-Component looks for
29 */
30 setUserId: any,
31 setMiddleware: any,
32 externalMiddleware?: any,
33
34 /**
35 * the id of the authentication-provider
36 */
37 userId?: any,
38
39
40}
41
42/**
43 * an entry specifies a kind of data that can be stored in a line of the table
44 */
45export default (props: IEntryArgs | any) => {
46
47 // the component must have the properties of IComponent
48 const componentProps: IInfrastructure & IComponent = {
49 infrastructureType: Types.INFRASTRUCTURE_TYPE_COMPONENT,
50 instanceType: ENTRY_INSTANCE_TYPE,
51 instanceId: props.id
52 };
53
54 const mwProps = {
55 middleware: createMiddleware({callback: (req, res, next) => {
56 console.log("this is the default mw of the SecuredEntry: ", props.id)
57
58 if (securedEntryProps.externalMiddleware) {
59 console.log("now using the provided middleware")
60 return new ConnectSequence(req, res, next)
61 .append(securedEntryProps.externalMiddleware.callback)
62 .run();
63 }
64 return next();
65
66 }})
67 };
68
69 const securedEntryProps: ISecuredEntryProps = {
70 //origRangeKey: props.rangeKey,
71
72 setUserId: (userId) => {
73 console.log(props.id, " received userId: ", userId)
74 securedEntryProps.userId = userId;
75 //props.rangeKey = IC_USER_ID
76 },
77
78 /**
79 * We MUST NOT OVERWRITE exisiting functions, only data. middleware is a function
80 * because they get not called
81 */
82
83 // the authentication-component replaces the middleware!
84 setMiddleware: (mw) => {
85 console.log(props.id, " received middleware: ", mw)
86 securedEntryProps.externalMiddleware = mw;
87 }
88 };
89
90 const entryProps: any = createEntryProps(Object.assign({}, props, componentProps, securedEntryProps));
91
92 const setUserIdFromContext = (context) => {
93
94 //console.log("check userId? ", entryProps, props, securedEntryProps)
95 // when called through ssr, we do not get the userId through the ICs. But the DataLayer-Integration puts
96 // it into the context for us
97
98 if (securedEntryProps && securedEntryProps.userId) {
99 console.log("SecuredEntry already has userId, not taking from context: ", securedEntryProps.userId);
100 return;
101 }
102
103 if (context && context.userId) {
104 if (securedEntryProps) {
105 securedEntryProps["userId"] = context["userId"];
106
107 } else {
108 console.error("no entryProps exist, cannot set userId")
109 }
110 return;
111 }
112
113 console.warn("no userId in context or in entryProps...")
114
115 };
116
117
118 return Object.assign(entryProps, {
119
120 // we need to adjust the writing into the table
121 setEntry: (args, context, tableName, isOffline) => {
122
123 setUserIdFromContext(context);
124
125
126 return setEntry(
127 tableName, //"code-architect-dev-data-layer",
128 props.primaryKey, // schema.Entry.ENTITY, //pkEntity
129 args[props.primaryKey], // pkId
130 IC_USER_ID, //schema.Data.ENTITY, // skEntity
131 `${securedEntryProps.userId}|${props.rangeKey}|${args[props.rangeKey]}`, // skId
132 Object.keys(args).reduce((result, key) => {
133 if (Object.keys(props.data).find(datakey => datakey === key) !== undefined) {
134 result[key] = args[key];
135 }
136 return result;
137 },{}), // jsonData,
138 isOffline
139
140 );
141 },
142
143 deleteEntry: (args, context, tableName, isOffline) => {
144
145 setUserIdFromContext(context);
146
147 return deleteEntry(
148 tableName, //"code-architect-dev-data-layer",
149 props.primaryKey, // schema.Entry.ENTITY, //pkEntity
150 args[props.primaryKey], // pkId
151 IC_USER_ID, //schema.Data.ENTITY, // skEntity
152 `${securedEntryProps.userId}|${props.rangeKey}|${args[props.rangeKey]}`, // skId
153 isOffline
154 );
155 },
156
157 listEntries: (args, context, tableName, key, isOffline) => {
158
159 setUserIdFromContext(context);
160
161 const entity = key === "pk" ? props.primaryKey : `${IC_USER_ID}|${securedEntryProps.userId}|${props.rangeKey}`;
162 const range = key === "pk" ? `${IC_USER_ID}|${securedEntryProps.userId}|${props.rangeKey}` : props.primaryKey;
163
164
165 return ddbListEntries(
166 tableName, //tablename
167 key, // key
168 entity, //entity
169 args[key === "pk" ? props.primaryKey : props.rangeKey], //value
170 range, //rangeEntity
171 isOffline
172 ).then(results => {
173
174 console.log("promised: ", results);
175 return results.map(item => {
176 const data = item.jsonData !== undefined ? JSON.parse(item.jsonData) : {};
177 data[props.primaryKey] = item.pk.substring(item.pk.lastIndexOf("|")+1);
178 data[props.rangeKey] = item.sk.substring(item.sk.lastIndexOf("|")+1);
179 return data;
180 });
181
182 });
183
184 },
185
186 }, mwProps);
187 // we provide the newly set middleware as last prop to overwrite the other values!
188
189};
190
191
192export const isSecuredEntry = (component) => {
193
194 return component !== undefined && component.instanceType === ENTRY_INSTANCE_TYPE;
195};
196
197
198
199const complementedProps = {
200
201 /*
202 createEntryFields: () => {
203 const fields = Object.keys(props.data).reduce((result, key)=> {
204 if (key !== securedEntryProps.origRangeKey) {
205 result[key] = {type: props.data[key]};
206 }
207
208
209 return result;
210 }, {});
211
212 fields[props.primaryKey] = {type: GraphQLString};
213 fields[IC_USER_ID] = {type: GraphQLString};
214
215 return fields;
216 },
217
218 createEntryType: (prefix) => {
219 return new GraphQLObjectType({
220 name: prefix+props.id,
221 fields: () => complementedProps.createEntryFields()
222 })
223 },
224
225 createKeyArgs: () => {
226
227 const args = {};
228
229 args[props.primaryKey] = {name: props.primaryKey, type: GraphQLString};
230 args[IC_USER_ID] = {name: IC_USER_ID, type: GraphQLString};
231
232 return args;
233 },* /
234
235 getEntryListQuery: (dictKey) => {
236 const fields = entryProps.createEntryFields();
237 //console.log("fields: ", fields);
238
239 return getEntryListQuery(
240 props.id,
241 dictKey,
242 fields,
243 {
244 userId: securedEntryProps.userId
245 } //context
246 );
247 },
248
249 setEntryMutation: (values) => {
250 const fields = entryProps.createEntryFields();
251 //console.log("fields: ", fields);
252
253 return setEntryMutation(
254 props.id,
255 values,
256 fields,
257 {
258 userId: securedEntryProps.userId
259 } //context
260 );
261
262 },
263
264 /*
265
266 // let's overwrite how the user can get the
267 getEntryListQuery: (dictKey) => {
268 const fields = complementedProps.createEntryFields();
269 //console.log("fields: ", fields);
270
271 // TODO, complement dictKey or even change the whole query ...
272 return getEntryListQuery(
273 props.id,
274 Object.keys(dictKey).reduce((res, key) => {
275 // we replace the rangeKey with the
276 if (key === securedEntryProps.origRangeKey) {
277 res[props.rangeKey] = `${securedEntryProps.clientId}|${securedEntryProps.origRangeKey}|${dictKey[key]}`
278 } else {
279 res[key] = dictKey[key];
280 }
281 return res;
282 }, {}),
283 fields
284 );
285 },
286
287 // this creates the input for the gql-tag: how the query is sent to apollo
288 setEntryMutation: (values) => {
289 const fields = complementedProps.createEntryFields();
290
291
292 return setEntryMutation(
293 props.id,
294 Object.keys(values).reduce((res, key) => {
295 // we replace the rangeKey with the
296 if (key === securedEntryProps.origRangeKey) {
297 res[props.rangeKey] = `${securedEntryProps.clientId}|${securedEntryProps.origRangeKey}|${values[key]}`
298 } else {
299 res[key] = values[key];
300 }
301 return res;
302 }, {}),
303 fields,
304 {
305 // we need to pass the clientId into the context of the gql-query for we don't have the value there yet!
306 clientId: securedEntryProps.clientId
307 } //context
308 );
309 }*/
310};
\No newline at end of file