Skip to content
66 linesCodeBlameRaw
1//! Where the window may go: the launcher, the server's pages, and the
2//! pages that sign someone in there. Any other address opens in the
3//! browser the system uses, and the window stays where it is. So do the
4//! server's pages for reading about g1t rather than using it (`OUTSIDE`):
5//! the window is for working in, the browser for browsing. bridge.js
6//! sends the same pages out when a link inside the site goes to one.
7
8use tauri::AppHandle;
9use tauri_plugin_opener::OpenerExt;
10use url::Url;
11
12use crate::config;
13
14/// Signing in with GitHub goes there and comes back.
15const SIGN_IN_HOSTS: &[&str] = &["github.com", "www.github.com"];
16
17/// The server's pages that open in the browser: pricing, policies,
18/// security, support, the desktop app's own downloads, and status. An
19/// entry ending in `/` is every page under it.
20pub const OUTSIDE: &[&str] = &["/pricing", "/policies", "/policies/", "/security", "/support", "/download", "/downloads/", "/status"];
21
22/// Whether a path on the server is one for the browser.
23pub fn outside(path: &str) -> bool {
24 let path = if path.len() > 1 { path.trim_end_matches('/') } else { path };
25 OUTSIDE.iter().any(|page| if page.ends_with('/') { path.starts_with(page) } else { path == *page })
26}
27
28/// Whether a page is one of signing in with GitHub's.
29pub fn signing_in(url: &Url) -> bool {
30 url.scheme() == "https" && url.host_str().is_some_and(|host| SIGN_IN_HOSTS.contains(&host))
31}
32
33/// Whether the window may load `url`.
34pub fn allowed(app: &AppHandle, url: &Url) -> bool {
35 match url.scheme() {
36 "about" | "blob" | "data" => return true,
37 "http" | "https" | "tauri" => {}
38 _ => return false,
39 }
40 if config::is_launcher(url) || (config::is_server(app, url) && !outside(url.path())) {
41 return true;
42 }
43 if signing_in(url) {
44 return true;
45 }
46 let _ = app.opener().open_url(url.as_str(), None::<&str>);
47 false
48}
49
50#[cfg(test)]
51mod tests {
52 use super::outside;
53
54 #[test]
55 fn reading_about_g1t_is_for_the_browser() {
56 assert!(outside("/pricing"));
57 assert!(outside("/pricing/"));
58 assert!(outside("/policies/terms"));
59 assert!(outside("/downloads/desktop/latest.json"));
60 assert!(!outside("/"));
61 assert!(!outside("/login"));
62 assert!(!outside("/acme/-/chat"));
63 assert!(!outside("/pricingx"));
64 assert!(!outside("/acme/security"));
65 }
66}