Skip to content

Commit 79f6fe5

Browse files
updated sample
1 parent 374d5cf commit 79f6fe5

12 files changed

Lines changed: 183 additions & 86 deletions

BoldBI.Winforms/BoldBI.Winforms.csproj

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<PlatformTarget>x64</PlatformTarget>
4747
<ErrorReport>prompt</ErrorReport>
4848
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
49-
<Prefer32Bit>true</Prefer32Bit>
49+
<Prefer32Bit>false</Prefer32Bit>
5050
</PropertyGroup>
5151
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
5252
<OutputPath>bin\x64\Release\</OutputPath>
@@ -56,18 +56,22 @@
5656
<PlatformTarget>x64</PlatformTarget>
5757
<ErrorReport>prompt</ErrorReport>
5858
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
59-
<Prefer32Bit>true</Prefer32Bit>
59+
<Prefer32Bit>false</Prefer32Bit>
6060
</PropertyGroup>
6161
<ItemGroup>
62-
<Reference Include="CefSharp, Version=117.2.40.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138, processorArchitecture=MSIL">
62+
<Reference Include="CefSharp">
6363
<HintPath>..\packages\CefSharp.Common.117.2.40\lib\net462\CefSharp.dll</HintPath>
6464
</Reference>
65-
<Reference Include="CefSharp.Core, Version=117.2.40.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138, processorArchitecture=MSIL">
65+
<Reference Include="CefSharp.Core">
6666
<HintPath>..\packages\CefSharp.Common.117.2.40\lib\net462\CefSharp.Core.dll</HintPath>
6767
</Reference>
68-
<Reference Include="CefSharp.WinForms, Version=117.2.40.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138, processorArchitecture=MSIL">
68+
<Reference Include="CefSharp.WinForms">
6969
<HintPath>..\packages\CefSharp.WinForms.117.2.40\lib\net462\CefSharp.WinForms.dll</HintPath>
7070
</Reference>
71+
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
72+
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
73+
</Reference>
74+
<Reference Include="System.Runtime.Serialization" />
7175
<Reference Include="System" />
7276
<Reference Include="System.Core" />
7377
<Reference Include="System.Xml.Linq" />
@@ -81,7 +85,7 @@
8185
<Reference Include="System.Xml" />
8286
</ItemGroup>
8387
<ItemGroup>
84-
<Compile Include="EmbedProperties.cs" />
88+
<Compile Include="EmbedDetails.cs" />
8589
<Compile Include="Form1.cs">
8690
<SubType>Form</SubType>
8791
</Compile>
@@ -121,6 +125,9 @@
121125
<ItemGroup>
122126
<Content Include="content\chromium.css" />
123127
<Content Include="scripts\EmbedBiWrapper.js" />
128+
<Content Include="embedConfig.json">
129+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
130+
</Content>
124131
</ItemGroup>
125132
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
126133
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

BoldBI.Winforms/EmbedDetails.cs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using System.IO;
3+
using System.Runtime.Serialization;
4+
using System.Runtime.Serialization.Json;
5+
using System.Text;
6+
7+
namespace BoldBI.Winforms
8+
{
9+
[DataContract]
10+
internal class EmbedDetails
11+
{
12+
[DataMember]
13+
public string DashboardId { get; set; }
14+
15+
[DataMember(Name = "ServerUrl")]
16+
public string ServerUrl { get; set; }
17+
18+
[DataMember]
19+
public string UserEmail { get; set; }
20+
21+
[DataMember]
22+
public string EmbedSecret { get; set; }
23+
24+
[DataMember]
25+
public string EmbedType { get; set; }
26+
27+
[DataMember]
28+
public string Environment { get; set; }
29+
30+
[DataMember]
31+
public string ExpirationTime { get; set; }
32+
33+
[DataMember]
34+
public string SiteIdentifier { get; set; }
35+
}
36+
37+
internal static class EmbedConfigProvider
38+
{
39+
public static EmbedDetails Current { get; private set; }
40+
41+
public static void Load(string filePath = null)
42+
{
43+
var path = filePath ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "embedConfig.json");
44+
if (!File.Exists(path))
45+
throw new FileNotFoundException("embedConfig.json not found", path);
46+
47+
string json;
48+
// Read with BOM detection
49+
using (var sr = new StreamReader(path, Encoding.UTF8, detectEncodingFromByteOrderMarks: true))
50+
{
51+
json = sr.ReadToEnd();
52+
}
53+
54+
if (string.IsNullOrWhiteSpace(json))
55+
throw new InvalidOperationException("embedConfig.json is empty.");
56+
57+
// Strip BOM if present
58+
if (json.Length > 0 && json[0] == '\uFEFF')
59+
json = json.Substring(1);
60+
61+
var ser = new DataContractJsonSerializer(typeof(EmbedDetails));
62+
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
63+
{
64+
Current = (EmbedDetails)ser.ReadObject(ms) as EmbedDetails;
65+
}
66+
67+
if (Current == null)
68+
throw new InvalidOperationException("Failed to deserialize embed configuration.");
69+
70+
if (!string.IsNullOrEmpty(Current.ServerUrl) && !Current.ServerUrl.EndsWith("/"))
71+
Current.ServerUrl += "/";
72+
73+
if (Current.SiteIdentifier == null)
74+
Current.SiteIdentifier = string.Empty;
75+
}
76+
}
77+
}

BoldBI.Winforms/EmbedProperties.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.

BoldBI.Winforms/Form1.cs

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using System;
22
using System.Net.Http;
33
using System.Text;
4+
using Newtonsoft.Json;
45
using System.Windows.Forms;
56
using System.IO;
6-
using System.Security.Cryptography;
77

88
namespace 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
}

BoldBI.Winforms/Program.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ static void Main()
2020
if (Environment.GetCommandLineArgs().Contains("--type=renderer"))
2121
Environment.Exit(0);
2222
}
23+
// Load embed configuration from embedConfig.json
24+
try
25+
{
26+
EmbedConfigProvider.Load();
27+
}
28+
catch (Exception ex)
29+
{
30+
MessageBox.Show("Failed to load embed configuration: " + ex.Message, "Configuration Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
31+
return;
32+
}
2333
Application.EnableVisualStyles();
2434
Application.SetCompatibleTextRenderingDefault(false);
2535
Application.Run(new Form1());

BoldBI.Winforms/packages.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
<package id="cef.redist.x64" version="117.2.4" targetFramework="net48" />
44
<package id="cef.redist.x86" version="117.2.4" targetFramework="net48" />
55
<package id="CefSharp.Common" version="117.2.40" targetFramework="net48" />
6-
<package id="CefSharp.WinForms" version="134.3.90" targetFramework="net48" />
6+
<package id="CefSharp.WinForms" version="117.2.40" targetFramework="net48" />
7+
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net48" />
78
</packages>

0 commit comments

Comments
 (0)