22#include "webview_impl.hpp"
32#include <freerdp/log.h>
33#include <winpr/string.h>
35#define TAG FREERDP_TAG("client.SDL.common.aad")
40 fkt_arg(
const std::string& url)
42 auto args = urlsplit(url);
43 auto redir = args.find(
"redirect_uri");
44 if (redir == args.end())
47 "[Webview] url %s does not contain a redirect_uri parameter, "
53 _redirect_uri = from_url_encoded_str(redir->second);
59 return !_redirect_uri.empty();
62 bool getCode(std::string& c)
const
68 bool handle(
const std::string& uri)
const
70 std::string duri = from_url_encoded_str(uri);
71 if (duri.length() < _redirect_uri.length())
73 auto rc = _strnicmp(duri.c_str(), _redirect_uri.c_str(), _redirect_uri.length());
77 bool parse(
const std::string& uri)
79 _args = urlsplit(uri);
80 auto err = _args.find(
"error");
81 if (err != _args.end())
83 auto suberr = _args.find(
"error_subcode");
84 WLog_ERR(TAG,
"[Webview] %s: %s, %s: %s", err->first.c_str(), err->second.c_str(),
85 suberr->first.c_str(), suberr->second.c_str());
88 auto val = _args.find(
"code");
89 if (val == _args.end())
91 WLog_ERR(TAG,
"[Webview] no code parameter detected in redirect URI %s", uri.c_str());
100 static std::string from_url_encoded_str(
const std::string& str)
103 auto cstr = winpr_str_url_decode(str.c_str(), str.length());
106 cxxstr = std::string(cstr);
112 static std::vector<std::string> split(
const std::string& input,
const std::string& regex)
115 std::regex re(regex);
116 std::sregex_token_iterator first{ input.begin(), input.end(), re, -1 };
117 std::sregex_token_iterator last;
118 return { first, last };
121 static std::map<std::string, std::string> urlsplit(
const std::string& url)
123 auto pos = url.find(
'?');
124 if (pos == std::string::npos)
128 auto surl = url.substr(pos);
129 auto args = split(surl,
"&");
131 std::map<std::string, std::string> argmap;
132 for (
const auto& arg : args)
134 auto kv = split(arg,
"=");
136 argmap.insert({ kv[0], kv[1] });
143 std::string _redirect_uri;
145 std::map<std::string, std::string> _args;
148static void fkt(webview_t webview,
const char* uri, webview_navigation_event_t type,
void* arg)
151 auto rcode =
static_cast<fkt_arg*
>(arg);
153 if (type != WEBVIEW_LOAD_FINISHED)
156 if (!rcode->handle(uri))
159 (void)rcode->parse(uri);
160 webview_terminate(webview);
163bool webview_impl_run(
const std::string& title,
const std::string& url, std::string& code)
165 webview::webview w(
false,
nullptr);
168 w.set_size(800, 600, WEBVIEW_HINT_NONE);
175 w.add_navigation_listener(fkt, &arg);
178 return arg.getCode(code);