eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1import Foundation
2
3// Invite-link parsing, shared by the iOS and Mac targets (and standalone-testable
4// like Crypto.swift — Foundation only, no UI imports).
5//
6// Two kinds of URL reach the apps from outside:
7// - the custom scheme the web welcome page fires:
8// elevenmessenger://add?url=<urlencoded https invite link>
9// - a universal link: the raw https invite link itself, #fragment included.
10// `inviteLink(fromOpenedURL:)` reduces either to the https invite-link string;
11// validating that string is the caller's job (each platform has its own parser).
12public func inviteLink(fromOpenedURL url: URL) -> String? {
13 switch url.scheme {
14 case "elevenmessenger":
15 // elevenmessenger://add?url=… — URLComponents percent-decodes the value.
16 guard let c = URLComponents(url: url, resolvingAgainstBaseURL: false),
17 c.host == "add",
18 let link = c.queryItems?.first(where: { $0.name == "url" })?.value
19 else { return nil }
20 return link
21 case "http", "https":
22 return url.absoluteString
23 default:
24 return nil
25 }
26}
27
28// Validate a new-format `/join/<slug>#<T>` link and reduce it to (origin, joinURL).
29// The fragment secret may carry the "e1." app-hint prefix or not (older links) —
30// both pass; join.js strips the prefix. Legacy `#k=` links are rejected — this
31// client targets only the keypair model.
32public func parseJoinLink(_ raw: String) -> (origin: String, joinURL: URL)? {
33 let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
34 guard let c = URLComponents(string: trimmed),
35 let scheme = c.scheme, let host = c.host,
36 scheme == "http" || scheme == "https",
37 c.path.contains("/join/"),
38 let frag = c.fragment, !frag.isEmpty, !frag.contains("k="),
39 let joinURL = URL(string: trimmed)
40 else { return nil }
41 var o = URLComponents()
42 o.scheme = scheme
43 o.host = host
44 o.port = c.port
45 guard let origin = o.url else { return nil }
46 return (origin.absoluteString, joinURL)
47}
48