diff --git a/README.md b/README.md
index ec35b044..424cc35e 100644
--- a/README.md
+++ b/README.md
@@ -87,7 +87,8 @@ sunshine needs access to uinput to create mouse and gamepad events:
- When Moonlight request you insert the correct pin on sunshine:
- Type in the URL bar of your browser: `https://xxx.xxx.xxx.xxx:47990` where `xxx.xxx.xxx.xxx` is the IP address of your computer
- Ignore any warning given by your browser about "insecure website"
- - Type in the username and password shown the first time you run Sunshine
+ - You should see a page containing both a new username and a password, needed to login into the next step
+ - Press "login" and log in using the credentials given above
- Go to "PIN" in the Header
- Type in your PIN and press Enter, you should get a Success Message
- Click on one of the Applications listed
diff --git a/assets/web/header-no-nav.html b/assets/web/header-no-nav.html
new file mode 100644
index 00000000..c6cf6993
--- /dev/null
+++ b/assets/web/header-no-nav.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ Sunshine
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/web/welcome.html b/assets/web/welcome.html
new file mode 100644
index 00000000..17b5c0c5
--- /dev/null
+++ b/assets/web/welcome.html
@@ -0,0 +1,30 @@
+
+
+
+
Welcome to Sunshine!
+
Before Getting Started, write down below these credentials
+
+
+ These Credentials down below are needed to access the rest of the application. Keep them safe, since you will never see them again!
+
+
+ Username:
+
+
+
+ Password:
+
+
+
Login
+
+
+
+
+
\ No newline at end of file
diff --git a/sunshine/config.cpp b/sunshine/config.cpp
index 02a5438a..2e5c8788 100644
--- a/sunshine/config.cpp
+++ b/sunshine/config.cpp
@@ -230,6 +230,8 @@ sunshine_t sunshine {
SUNSHINE_CONFIG_DIR "/sunshine.conf", // config file
{}, // cmd args
47989,
+ false, // show credentials,
+ ""
};
bool endline(char ch) {
diff --git a/sunshine/config.h b/sunshine/config.h
index 3c0537dd..a013c525 100644
--- a/sunshine/config.h
+++ b/sunshine/config.h
@@ -109,6 +109,9 @@ struct sunshine_t {
} cmd;
std::uint16_t port;
+
+ bool showCredentials;
+ std::string plainPassword;
};
extern video_t video;
diff --git a/sunshine/confighttp.cpp b/sunshine/confighttp.cpp
index c1a643bb..20beaa6e 100644
--- a/sunshine/confighttp.cpp
+++ b/sunshine/confighttp.cpp
@@ -73,6 +73,15 @@ void send_unauthorized(resp_https_t response, req_https_t request) {
response->write(SimpleWeb::StatusCode::client_error_unauthorized, headers);
}
+void send_redirect(resp_https_t response, req_https_t request, const char *path) {
+ auto address = request->remote_endpoint_address();
+ BOOST_LOG(info) << "Web UI: ["sv << address << "] -- not authorized"sv;
+ const SimpleWeb::CaseInsensitiveMultimap headers {
+ { "Location", path }
+ };
+ response->write(SimpleWeb::StatusCode::redirection_temporary_redirect, headers);
+}
+
bool authenticate(resp_https_t response, req_https_t request) {
auto address = request->remote_endpoint_address();
auto ip_type = net::from_address(address);
@@ -87,6 +96,13 @@ bool authenticate(resp_https_t response, req_https_t request) {
send_unauthorized(response, request);
});
+ //If credentials are shown, redirect the user to a /welcome page
+ if(config::sunshine.showCredentials){
+ send_redirect(response,request,"/welcome");
+ fg.disable();
+ return false;
+ }
+
auto auth = request->header.find("authorization");
if(auth == request->header.end()) {
return false;
@@ -185,6 +201,17 @@ void getPasswordPage(resp_https_t response, req_https_t request) {
response->write(header + content);
}
+void getWelcomePage(resp_https_t response, req_https_t request) {
+ print_req(request);
+ if(!config::sunshine.showCredentials){
+ send_redirect(response,request,"/");
+ return;
+ }
+ std::string header = read_file(WEB_DIR "header-no-nav.html");
+ std::string content = read_file(WEB_DIR "welcome.html");
+ response->write(header + content);
+}
+
void getApps(resp_https_t response, req_https_t request) {
if(!authenticate(response, request)) return;
@@ -335,6 +362,29 @@ void getConfig(resp_https_t response, req_https_t request) {
}
}
+void getPlainPassword(resp_https_t response, req_https_t request) {
+
+ print_req(request);
+
+ pt::ptree outputTree;
+ auto g = util::fail_guard([&]() {
+ std::ostringstream data;
+
+ pt::write_json(data, outputTree);
+ response->write(data.str());
+ });
+
+ if(config::sunshine.showCredentials){
+ outputTree.put("status", "true");
+ outputTree.put("username", config::sunshine.username);
+ outputTree.put("password", config::sunshine.plainPassword);
+ config::sunshine.showCredentials = false;
+ config::sunshine.plainPassword = "";
+ } else {
+ outputTree.put("status", "false");
+ }
+}
+
void saveConfig(resp_https_t response, req_https_t request) {
if(!authenticate(response, request)) return;
@@ -467,6 +517,7 @@ void start() {
server.resource["^/clients$"]["GET"] = getClientsPage;
server.resource["^/config$"]["GET"] = getConfigPage;
server.resource["^/password$"]["GET"] = getPasswordPage;
+ server.resource["^/welcome$"]["GET"] = getWelcomePage;
server.resource["^/api/pin"]["POST"] = savePin;
server.resource["^/api/apps$"]["GET"] = getApps;
server.resource["^/api/apps$"]["POST"] = saveApp;
@@ -474,6 +525,7 @@ void start() {
server.resource["^/api/config$"]["POST"] = saveConfig;
server.resource["^/api/password$"]["POST"] = savePassword;
server.resource["^/api/apps/([0-9]+)$"]["DELETE"] = deleteApp;
+ server.resource["^/api/setup/password$"]["GET"] = getPlainPassword;
server.config.reuse_address = true;
server.config.address = "0.0.0.0"s;
server.config.port = port_https;
diff --git a/sunshine/httpcommon.cpp b/sunshine/httpcommon.cpp
index 1f3b1dc5..0520a4f8 100644
--- a/sunshine/httpcommon.cpp
+++ b/sunshine/httpcommon.cpp
@@ -94,8 +94,12 @@ int save_user_creds(const std::string &file, const std::string &username, const
BOOST_LOG(info) << "New credentials have been created"sv;
if(run_our_mouth) {
- BOOST_LOG(info) << "Username: "sv << username;
- BOOST_LOG(info) << "Password: "sv << password;
+ //BOOST_LOG(info) << "Username: "sv << username;
+ //BOOST_LOG(info) << "Password: "sv << password;
+ BOOST_LOG(info) << "Open the Web UI to see your new username and password";
+ //Save these two in memory to show user and password the first time Sunshine is started
+ config::sunshine.showCredentials = true;
+ config::sunshine.plainPassword = password;
}
return 0;