11using System ;
22using System . Net . Http ;
33using System . Text ;
4+ using Newtonsoft . Json ;
45using System . Windows . Forms ;
56using System . IO ;
6- using System . Security . Cryptography ;
77
88namespace BoldBI . Winforms
99{
@@ -21,55 +21,75 @@ public Form1()
2121
2222 public void GetEmbedDetails ( )
2323 {
24- decimal time = ( decimal ) Math . Round ( ( DateTime . Now . ToUniversalTime ( ) - new DateTime ( 1970 , 1 , 1 ) ) . TotalMilliseconds / 1000 ) ;
25- var dashboardServerApiUrl = EmbedProperties . RootUrl + "api/" + EmbedProperties . SiteIdentifier ;
24+ var siteId = string . IsNullOrEmpty ( EmbedConfigProvider . Current . SiteIdentifier ) ? "" : EmbedConfigProvider . Current . SiteIdentifier ;
2625
27- var embedQuerString = "embed_nonce=" + Guid . NewGuid ( ) +
28- "&embed_dashboard_id=" + EmbedProperties . DashboardId +
29- "&embed_timestamp=" + Math . Round ( time ) +
30- "&embed_expirationtime=100000" ;
31- embedQuerString += "&embed_user_email=" + EmbedProperties . UserEmail ;
32- //To set embed_server_timestamp to overcome the EmbedCodeValidation failing while different timezone using at client application.
33- double timeStamp = ( int ) DateTime . UtcNow . Subtract ( new DateTime ( 1970 , 1 , 1 ) ) . TotalSeconds ;
34- embedQuerString += "&embed_server_timestamp=" + timeStamp ;
35- var embedDetailsUrl = "/embed/authorize?" + embedQuerString + "&embed_signature=" + GetSignatureUrl ( embedQuerString ) ;
26+ // Prepare embed generation payload
27+ var embedDetails = new
28+ {
29+ email = EmbedConfigProvider . Current . UserEmail ,
30+ serverurl = EmbedConfigProvider . Current . ServerUrl ,
31+ siteidentifier = siteId ,
32+ embedsecret = EmbedConfigProvider . Current . EmbedSecret ,
33+ dashboard = new { id = EmbedConfigProvider . Current . DashboardId }
34+ } ;
35+
36+ string accessToken = null ;
3637
3738 using ( var client = new HttpClient ( ) )
3839 {
39- client . BaseAddress = new Uri ( dashboardServerApiUrl ) ;
40- client . DefaultRequestHeaders . Accept . Clear ( ) ;
40+ // POST to BoldBI embed authorize endpoint to get access token
41+ var requestUrl = EmbedConfigProvider . Current . ServerUrl . TrimEnd ( '/' ) + "/api/" + siteId + "/embed/authorize" ;
42+ var jsonPayload = JsonConvert . SerializeObject ( embedDetails ) ;
43+ var httpContent = new StringContent ( jsonPayload , Encoding . UTF8 , "application/json" ) ;
44+
45+ var result = client . PostAsync ( requestUrl , httpContent ) . Result ;
46+ var resultContent = result . Content . ReadAsStringAsync ( ) . Result ;
47+
48+ // Try to extract access token from response
49+ try
50+ {
51+ dynamic tokenResp = JsonConvert . DeserializeObject < dynamic > ( resultContent ) ;
52+ if ( tokenResp != null )
53+ {
54+ if ( tokenResp . Data != null && tokenResp . Data . access_token != null )
55+ accessToken = ( string ) tokenResp . Data . access_token ;
56+ else if ( tokenResp . access_token != null )
57+ accessToken = ( string ) tokenResp . access_token ;
58+ else if ( tokenResp . data != null && tokenResp . data . access_token != null )
59+ accessToken = ( string ) tokenResp . data . access_token ;
60+ }
61+ }
62+ catch { /* ignore parse errors */ }
63+
64+ if ( string . IsNullOrEmpty ( accessToken ) )
65+ {
66+ // Fallback: use raw response if token extraction failed
67+ accessToken = resultContent ;
68+ }
4169
42- var result = client . GetAsync ( dashboardServerApiUrl + embedDetailsUrl ) . Result ;
43- string resultContent = result . Content . ReadAsStringAsync ( ) . Result ;
44- //webBrowser1.ObjectForScripting = this;
70+ // Build HTML embedding page and inject embedToken
4571 var htmlString = new StringBuilder ( ) ;
46- htmlString . Append ( "<!DOCTYPE html><html><head><link rel='stylesheet' href='" + System . AppDomain . CurrentDomain . BaseDirectory . Replace ( "bin\\ x64\\ Debug\\ " , "" ) + "content\\ chromium.css'/><script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script><script src='https://cdn.polyfill.io/v2/polyfill.min.js'></script><script type='text/javascript' src='https://cdn.boldbi.com/embedded-sdk/latest/boldbi-embed.js'></script></script><script type='text/javascript'>$(document).ready(function() {this.dashboard = BoldBI.create({ serverUrl:'" + EmbedProperties . RootUrl + EmbedProperties . SiteIdentifier + "', dashboardId:'" + EmbedProperties . DashboardId + "',embedContainerId: 'dashboard',embedType:'" + EmbedProperties . EmbedType + "',environment:'" + EmbedProperties . Environment + "',width: window.innerWidth - 20 + 'px',height: window.innerHeight - 20 + 'px',expirationTime: 100000,authorizationServer:{url: '', data:" + resultContent + "},dashboardSettings:{showExport: false,showRefresh: false,showMoreOption: false}});console.log(this.dashboard);this.dashboard.loadDashboard();});</script></head><body style='background-color: white'><div id ='viewer-section' style='background-color: white'><div id ='dashboard'></div></div></body></html>" ) ;
72+ var serverUrlForJs = EmbedConfigProvider . Current . ServerUrl . TrimEnd ( '/' ) + "/" + EmbedConfigProvider . Current . SiteIdentifier ;
73+ var environment = EmbedConfigProvider . Current . Environment ;
74+
75+ var cssPath = System . AppDomain . CurrentDomain . BaseDirectory . Replace ( "bin\\ x64\\ Debug\\ " , "" ) + "content\\ chromium.css" ;
76+ htmlString . Append ( "<!DOCTYPE html><html><head><link rel='stylesheet' href='" + cssPath + "'/><script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script><script src='https://cdn.polyfill.io/v2/polyfill.min.js'></script><script type='text/javascript' src='https://cdn.boldbi.com/embedded-sdk/latest/boldbi-embed.js'></script>" ) ;
77+
78+ // Use JsonConvert.ToString(accessToken) to ensure the token is properly escaped as a JS string literal
79+ htmlString . Append ( "<script type='text/javascript'>$(document).ready(function() {this.dashboard = BoldBI.create({ serverUrl:'" + serverUrlForJs + "', dashboardId:'" + EmbedConfigProvider . Current . DashboardId + "', embedContainerId: 'dashboard', embedToken: " + JsonConvert . ToString ( accessToken ) + ", environment:'" + environment + "', width: window.innerWidth - 20 + 'px', height: window.innerHeight - 20 + 'px' " + "}); this.dashboard.loadDashboard(); });</script></head><body style='background-color: white'><div id ='viewer-section' style='background-color: white'><div id ='dashboard'></div></div></body></html>" ) ;
80+
4781 string filePath = AppDomain . CurrentDomain . BaseDirectory + "EmbedWrapper.html" ;
4882 if ( File . Exists ( filePath ) )
4983 {
5084 File . Delete ( filePath ) ;
5185 }
5286 using ( FileStream fs = new FileStream ( filePath , FileMode . Create ) )
87+ using ( StreamWriter wr = new StreamWriter ( fs , Encoding . UTF8 ) )
5388 {
54- using ( StreamWriter wr = new StreamWriter ( fs , Encoding . UTF8 ) )
55- {
56- wr . Write ( htmlString . ToString ( ) ) ;
57- }
89+ wr . Write ( htmlString . ToString ( ) ) ;
5890 }
5991 Url = filePath ;
6092 }
6193 }
62-
63- public string GetSignatureUrl ( string message )
64- {
65- var encoding = new System . Text . UTF8Encoding ( ) ;
66- var keyBytes = encoding . GetBytes ( EmbedProperties . EmbedSecret ) ;
67- var messageBytes = encoding . GetBytes ( message ) ;
68- using ( var hmacsha1 = new HMACSHA256 ( keyBytes ) )
69- {
70- var hashMessage = hmacsha1 . ComputeHash ( messageBytes ) ;
71- return Convert . ToBase64String ( hashMessage ) ;
72- }
73- }
7494 }
7595}
0 commit comments