import React, {ReactNode} from 'react'; import uuidv4 from 'uuid/v4'; import {IComponent} from "../types/component"; import Types, { IInfrastructure } from "../types"; import createMiddleware, { isMiddleware } from '../middleware/middleware-component'; import createWebApp, { isWebApp } from '../webapp/webapp-component'; import { getChildrenArray, findComponentRecursively } from '../libs'; import cookiesMiddleware from 'universal-cookie-express'; export const IDENTITY_INSTANCE_TYPE = "IdentityComponent"; export const getBrowserId = (req, key=IDENTITY_KEY) => { const browserId = req.universalCookies.get(key); if (browserId !== undefined) { return browserId; } else { const newId = uuidv4(); req.universalCookies.set(key, newId); return newId; } } export const IDENTITY_KEY ="IC_IDENTITY_KEY"; /** * Specifies all the properties that a Authentication-Component must have */ export interface IIdentityArgs { } /** * specifies the properties that an Identity-Component has during runtime */ export interface IIdentityProps { /** * Function that allows the identity to store the user-data * filled by the DataLayer * * @storeData: a function that storesData */ setStoreData: ( storeData: (pkEntity: string, pkVal: any, skEntity: string, skVal: any, jsonData: any) => void ) => void storeData?: (pkEntity: string, pkVal: any, skEntity: string, skVal: any, jsonData: any) => void, setGetData: ( storeData: (pkEntity: string, pkVal: any, skEntity: string, skVal: any) => any ) => void getData?: (pkEntity: string, pkVal: any, skEntity: string, skVal: any) => any } /** * The Identity-Component uses cookies to uniquely identify a browser * * @param props */ export default (props: IIdentityArgs | any) => { //console.log ("Identity: ",props ); const componentProps: IInfrastructure & IComponent = { infrastructureType: Types.INFRASTRUCTURE_TYPE_COMPONENT, instanceType: IDENTITY_INSTANCE_TYPE, instanceId: undefined, // authentications cannot be found programmatically?! }; const identityProps: IIdentityProps = { setStoreData: (storeData: (pkEntity: string, pkVal: any, skEntity: string, skVal: any, jsonData: any) => void) => { //console.log("setStoreData: ",storeData) props.storeData = storeData; }, setGetData: (getData: (pkEntity: string, pkVal: any, skEntity: string, skVal: any) => void) => { //console.log("setStoreData: ",storeData) props.getData = getData; } } // if the child needs to store data that belongs to the user, provide a function to do so! findComponentRecursively(props.children, (child) => child.setStoreIdentityData !== undefined).forEach( child => { child.setStoreIdentityData( async function (request: any, secondaryKey: string, val: any, jsonData: any) { //console.log("identity: storeData: ", props); return await props.storeData( IDENTITY_KEY, //pkEntity: string, getBrowserId(request, IDENTITY_KEY), //pkVal: any, secondaryKey, //skEntity: string, val, //skVal: any, jsonData //: any ) } ); child.setGetIdentityData( async function (request: any, matchBrowserIdentity: boolean, secondaryKey: string, val: any) { //console.log("identity: storeData: ", props); return await props.getData( IDENTITY_KEY, //pkEntity: string, matchBrowserIdentity ? getBrowserId(request, IDENTITY_KEY) : undefined, //pkVal: any, secondaryKey, //skEntity: string, val //skVal: any, ) } ); }); /** * The Identity requires cookies to store an uuid */ const mappedChildren = { // we provide the middlewares that we require children: [ // we need to use cookies in order to verify whether a user is logged in createMiddleware({ callback: cookiesMiddleware() }), // here we provide all interested children with the identity - on server side only! // but for the browser, we provide the cookie createMiddleware({ callback: (req, res, next) => { //console.log("this it the identity-mw") findComponentRecursively(props.children, (child) => child.setIdentity !== undefined).forEach( child => { child.setIdentity(getBrowserId(req, IDENTITY_KEY)); }); return next(); }}) ].concat(props.children) }; //console.log("mapped children: ", mappedChildren.children.filter(c=> isWebApp(c)).map(c=> c.routes.map(r=>r.middlewares))); //console.log("identity children: ", findComponentRecursively(props.children, isWebApp)); //console.log("identity mapped children: ", findComponentRecursively(mappedChildren.children, isWebApp)); return Object.assign(props, componentProps, identityProps, mappedChildren); }; export const isIdentity = (component) => { return component !== undefined && component.instanceType === IDENTITY_INSTANCE_TYPE; };