Skip to content

Added request headers to all EE event details payload #1541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion client/packages/lowcoder-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lowcoder-sdk",
"version": "2.6.3",
"version": "2.6.4",
"type": "module",
"files": [
"src",
Expand All @@ -25,6 +25,9 @@
},
"./dist/style.css": {
"import": "./dist/style.css"
},
"./dist/chunks/": {
"import": "./dist/chunks/"
}
},
"scripts": {
Expand Down
79 changes: 25 additions & 54 deletions client/packages/lowcoder-sdk/vite.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,7 @@ export const viteConfig: UserConfig = {
},
base: ensureLastSlash(process.env.PUBLIC_URL),
build: {
minify: "terser",
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
pure_funcs: ["console.info", "console.debug", "console.log"],
},
format: {
comments: false,
},
},
minify: "terser",
chunkSizeWarningLimit: 500,
lib: {
formats: ["es"],
Expand All @@ -56,46 +46,31 @@ export const viteConfig: UserConfig = {
},
rollupOptions: {
treeshake: {
moduleSideEffects: false,
moduleSideEffects: true,
propertyReadSideEffects: false,
tryCatchDeoptimization: false,
unknownGlobalSideEffects: false,
},
external: ["react", "react-dom"],
output: {
chunkFileNames: "chunks/[name]-[hash].js",
entryFileNames: "entry/[name]-[hash].js",
assetFileNames: "assets/[name]-[hash].[ext]",
entryFileNames: "lowcoder-sdk.js",
assetFileNames: "style.css",
manualChunks: (id) => {
if (id.includes("node_modules")) {
// CORE FRAMEWORK CHUNKS
if (id.includes("react")) return "react";
if (id.includes("react-dom")) return "react-dom";
if (id.includes("react-router")) return "react-router";
if (id.includes("react-redux")) return "react-redux";
if (id.includes("redux")) return "redux";
if (id.includes("redux-saga")) return "redux-saga";

// UI LIBRARIES
if (id.includes("@ant-design/icons")) return "ant-design-icons";
if (id.includes("antd")) return "antd";
if (id.includes("node_modules/antd")) return "antd";
if (id.includes("styled-components")) return "styled-components";

// 🔹 BARCODE & QR CODE PROCESSING
if (id.includes("zxing") || id.includes("Barcode") || id.includes("QRCode") || id.includes("PDF417")) return "barcode";

// CHARTING & DATA VISUALIZATION
if (id.includes("echarts")) return "echarts";
if (id.includes("echarts-wordcloud")) return "echarts-wordcloud";
if (id.includes("d3")) return "d3";
if (id.includes("react-qr-barcode-scanner")) return "barcode";

// TEXT EDITORS & PARSERS
if (id.includes("codemirror")) return "codemirror";
if (id.includes("quill")) return "quill";
if (id.includes("react-json-view")) return "react-json-view";
if (id.includes("react-markdown")) return "react-markdown";
if (id.includes("react-quill")) return "react-quill";
if (id.includes("remark") || id.includes("rehype") || id.includes("markdown")) return "markdown-parsers";
if (id.includes("remark-gfm")) return "remark-gfm";
if (id.includes("rehype-raw")) return "rehype-raw";
if (id.includes("rehype-sanitize")) return "rehype-sanitize";
Expand Down Expand Up @@ -133,7 +108,6 @@ export const viteConfig: UserConfig = {
if (id.includes("xlsx")) return "xlsx";
if (id.includes("alasql")) return "alasql";
if (id.includes("sql-formatter")) return "sql-formatter";
if (id.includes("tern")) return "tern";

// NETWORK & HTTP
if (id.includes("axios")) return "axios";
Expand All @@ -158,41 +132,38 @@ export const viteConfig: UserConfig = {
if (id.includes("cnchar")) return "cnchar";
if (id.includes("hotkeys-js")) return "hotkeys-js";
if (id.includes("loglevel")) return "loglevel";
if (id.includes("qrcode-react")) return "qrcode-react";
if (id.includes("qrcode.react")) return "qrcode-react";
if (id.includes("react-joyride")) return "react-joyride";
if (id.includes("rc-trigger")) return "rc-trigger";
if (id.includes("really-relaxed-json")) return "really-relaxed-json";
if (id.includes("simplebar-react")) return "simplebar-react";
return "vendor";
if (id.includes("react-documents")) return "react-documents";
if (id.includes("react-colorful")) return "react-colorful";
if (id.includes("react-best-gradient-color-picker")) return "react-best-gradient-color-picker";
if (id.includes("@supabase/supabase-js")) return "supabase";
return null;
}
if (id.includes("src/api")) return "api";
if (id.includes("src/appView")) return "appView";
if (id.includes("src/base")) return "base";
if (id.includes("src/constants")) return "constants";
if (id.includes("src/i18n")) return "i18n";
if (id.includes("src/ide")) return "ide";
if (id.includes("src/layout")) return "layout";
if (id.includes("src/pages")) return "pages";
if (id.includes("src/redux")) return "app_redux";
if (id.includes("src/comps")) return "comps";
if (id.includes("comps/comps")) return "comps2";
if (id.includes("comps/controls")) return "controls";
if (id.includes("comps/queries")) return "queries";
if (id.includes("comps/utils")) return "utils";
if (id.includes("src/hooks")) return "hooks";
if (id.includes("src/util")) return "util";
return "common"; // 📦 Internal app shared code
},
return null;
}
},
experimental: {
minChunkSize: 300000, // 📏 Force smaller chunks (~300KB)
},
plugins: [
terser(),
terser({
compress: {
drop_console: true,
drop_debugger: true,
pure_funcs: ["console.info", "console.debug", "console.log"],
},
format: {
comments: /(@vite-ignore|webpackIgnore)/
},
}) as PluginOption,
strip({
functions: ["console.log", "debugger"], // ✅ Remove logs
sourceMap: true,
}),
}) as PluginOption,
],
onwarn: (warning, warn) => {
if (warning.code === 'MODULE_LEVEL_DIRECTIVE') {
Expand Down
2 changes: 1 addition & 1 deletion server/api-service/lowcoder-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<dependency>
<groupId>org.lowcoder.plugin</groupId>
<artifactId>lowcoder-plugin-api</artifactId>
<version>2.3.0</version>
<version>2.3.1</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.lowcoder.plugin.api.event.LowcoderEvent;
import org.lowcoder.sdk.constants.GlobalContext;
import reactor.util.context.ContextView;

import java.lang.reflect.Field;
import java.util.HashMap;
Expand All @@ -19,6 +21,7 @@ public abstract class AbstractEvent implements LowcoderEvent
protected final Boolean isAnonymous;
private final String ipAddress;
protected Map<String, Object> details;
protected Map<String, String> eventHeaders;
@Setter
private static String environmentID;

Expand All @@ -42,7 +45,10 @@ public B detail(String name, String value)
}
}

public void populateDetails() {
public void populateDetails(ContextView contextView) {
//populate eventHeaders field
eventHeaders = contextView.get(GlobalContext.HEADERS);

if (details == null) {
details = new HashMap<>();
}
Expand All @@ -57,5 +63,8 @@ public void populateDetails() {

}
details.put("environmentId", environmentID);
if(!details.containsKey("headers")) {
details.put("headers", eventHeaders);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ public class GlobalContext {

public static final String CURRENT_ORG_MEMBER = "currentOrgMember";
public static final String DOMAIN = "domain";
public static final String HEADERS = "headers";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import reactor.util.context.ContextView;

import java.nio.charset.StandardCharsets;
import java.util.Optional;
Expand All @@ -40,7 +41,7 @@ public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String token = contextView.get(VISITOR_TOKEN);
((Mono<OrgMember>) contextView.get(CURRENT_ORG_MEMBER))
.flatMap(orgMember -> {
emitEvent(exchange.getRequest(), token, orgMember);
emitEvent(exchange.getRequest(), token, orgMember, contextView);
return Mono.empty();
})
.subscribeOn(Schedulers.boundedElastic())
Expand All @@ -51,7 +52,7 @@ public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
);
}

private void emitEvent(ServerHttpRequest request, String token, OrgMember orgMember) {
private void emitEvent(ServerHttpRequest request, String token, OrgMember orgMember, ContextView contextView) {
MultiValueMap<String, String> headers = writableHttpHeaders(request.getHeaders());
headers.remove("Cookie");
Optional<String> ipAddressOptional = headers.remove("X-Real-IP").stream().findFirst();
Expand All @@ -69,7 +70,7 @@ private void emitEvent(ServerHttpRequest request, String token, OrgMember orgMem
.queryParams(request.getQueryParams())
.ipAddress(ipAddress)
.build();
event.populateDetails();
event.populateDetails(contextView);

log.debug("API call event emitted for '{}' from org '{}' on URI: {}", orgMember.getUserId(), orgMember.getUserId(), request.getURI().getPath());
applicationEventPublisher.publishEvent(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
Expand All @@ -32,6 +33,7 @@
import static org.lowcoder.sdk.constants.Authentication.isAnonymousUser;
import static org.lowcoder.sdk.constants.GlobalContext.*;
import static org.lowcoder.sdk.util.IDUtils.generate;
import static org.springframework.http.HttpHeaders.writableHttpHeaders;

@Component
@RequiredArgsConstructor
Expand Down Expand Up @@ -107,6 +109,11 @@ private Map<String, Object> buildContextMap(ServerWebExchange serverWebExchange,
contextMap.put(CURRENT_ORG_MEMBER, orgMemberService.getCurrentOrgMember(visitorId).cache());
contextMap.put(VISITOR_TOKEN, cookieHelper.getCookieToken(serverWebExchange));
contextMap.put(DOMAIN, UriUtils.getRefererDomainFromRequest(serverWebExchange));

//Analytics related fields
MultiValueMap<String, String> headers = writableHttpHeaders(request.getHeaders());
headers.remove("Cookie");
contextMap.put(HEADERS, headers);
return contextMap;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ public Object handleAPICallEvent(ProceedingJoinPoint joinPoint) throws Throwable
return sessionUserService.getVisitorToken()
.zipWith(sessionUserService.getVisitorOrgMemberCacheSilent().defaultIfEmpty(OrgMember.NOT_EXIST))
.zipWith(ReactiveRequestContextHolder.getRequest())
.doOnNext(
.delayUntil(
tuple -> {
String token = tuple.getT1().getT1();
OrgMember orgMember = tuple.getT1().getT2();
ServerHttpRequest request = tuple.getT2();
if (orgMember == OrgMember.NOT_EXIST) {
return;
return Mono.empty();
}
MultiValueMap<String, String> headers = writableHttpHeaders(request.getHeaders());
headers.remove("Cookie");
Expand All @@ -77,8 +77,11 @@ public Object handleAPICallEvent(ProceedingJoinPoint joinPoint) throws Throwable
.queryParams(request.getQueryParams())
.ipAddress(ipAddress)
.build();
event.populateDetails();
applicationEventPublisher.publishEvent(event);
return Mono.deferContextual(contextView -> {
event.populateDetails(contextView);
applicationEventPublisher.publishEvent(event);
return Mono.empty();
});
})
.onErrorResume(throwable -> {
log.error("handleAPICallEvent error {} for: {} ", joinPoint.getSignature().getName(), EventType.API_CALL_EVENT, throwable);
Expand Down
Loading
Loading