Skip to content

Commit

Permalink
Inject scripts into extension context
Browse files Browse the repository at this point in the history
  • Loading branch information
JingMatrix committed Jul 22, 2023
1 parent 4726e01 commit 28f2779
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 18 deletions.
78 changes: 77 additions & 1 deletion app/src/main/assets/extension.js
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
// Browser APIs will be implement in front-end
const inFrame = typeof globalThis.ChromeXt == "undefined";

class Runtime {
constructor(manifest) {
this.manifest = manifest;
}
getManifest() {
return this.manifest;
}
}

window.chrome = {
accessibilityFeatures: {},
action: {},
alarms: {},
browser: {},
browserAction: {},
browsingData: {},
bookmarks: {},
commandsw: {},
contentSettings: {},
contextMenus: {},
cookies: {},
declarativeContent: {},
declarativeWebRequest: {},
devtools: {},
documentScan: {},
downloads: {},
enterprise: {},
events: {},
extension: {},
fileBrowserHandler: {},
fontSettings: {},
gcm: {},
history: {},
i18n: {},
identity: {},
idle: {},
input: {},
loginState: {},
management: {},
networking: {},
notifications: {},
offscreen: {},
omnibox: {},
pageAction: {},
pageCapture: {},
permissions: {},
platformKeys: {},
power: {},
printerProvider: {},
privacy: {},
proxy: {},
runtime: new Runtime(extension),
search: {},
serial: {},
scripting: {},
scriptBadge: {},
sessions: {},
sidePanel: {},
storage: {},
socket: {},
system: {},
tabCapture: {},
tabs: {},
tabGroups: {},
topSites: {},
tts: {},
ttsEngine: {},
types: {},
vpnProvider: {},
wallpaper: {},
webNavigation: {},
webRequest: {},
webstore: {},
windows: {},
};
6 changes: 2 additions & 4 deletions app/src/main/java/org/matrix/chromext/Listener.kt
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,8 @@ object Listener {
}
}
"extension" -> {
if (payload == "") {
callback =
LocalFiles.script +
"window.dispatchEvent(new CustomEvent('extension', ${LocalFiles.start()}));"
if (payload == "" && BuildConfig.DEBUG) {
callback = "window.dispatchEvent(new CustomEvent('extension', ${LocalFiles.start()}));"
}
}
"websocket" -> {
Expand Down
42 changes: 30 additions & 12 deletions app/src/main/java/org/matrix/chromext/extension/LocalFiles.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,36 @@ object LocalFiles {
}
}

private fun serveFiles(path: String, connection: Socket) {
private fun serveFiles(id: String, connection: Socket) {
val path = directory.toString() + "/" + id
val background = extensions.get(id)?.optJSONObject("background")?.optString("page")
runCatching {
connection.inputStream.bufferedReader().use {
val requestLine = it.readLine()
if (requestLine == null) {
connection.close()
return
}
val request = requestLine.split(" ")
if (request[0] == "GET" && request[2] == "HTTP/1.1") {
val name = request[1]
val file = File(path + name)
if (file.exists()) {
val data = file.readBytes()
if (!file.exists() && name != "/ChromeXt.js") {
connection.outputStream.write("HTTP/1.1 404 Not Found\r\n\r\n".toByteArray())
} else if (file.isDirectory() || name.contains("..")) {
connection.outputStream.write("HTTP/1.1 403 Forbidden\r\n\r\n".toByteArray())
} else {
val data =
if (name == "/" + background) {
val html = FileReader(file).use { it.readText() }
html
.replaceFirst("<head>", "<head>\n<script src='/ChromeXt.js'></script>")
.toByteArray()
} else if (name == "/ChromeXt.js") {
("const extension = ${extensions.get(id)!!};\n" + script).toByteArray()
} else {
file.readBytes()
}
val type = URLConnection.guessContentTypeFromName(name) ?: "text/plain"
val response =
arrayOf(
Expand All @@ -52,8 +72,6 @@ object LocalFiles {
connection.outputStream.write(
(response.joinToString("\r\n") + "\r\n\r\n").toByteArray())
connection.outputStream.write(data)
} else {
connection.outputStream.write("HTTP/1.1 404 Not Found\r\n\r\n".toByteArray())
}
connection.close()
}
Expand All @@ -62,28 +80,28 @@ object LocalFiles {
.onFailure { Log.ex(it) }
}

private fun startServer(name: String) {
if (extensions.containsKey(name) && !extensions.get(name)!!.has("port")) {
private fun startServer(id: String) {
if (extensions.containsKey(id) && !extensions.get(id)!!.has("port")) {
val server = ServerSocket()
server.bind(null)
val port = server.getLocalPort()
Log.d("Listening at port ${port}")
Log.d("Listening at port ${port} for ${id}")
thread {
runCatching {
while (true) {
val socket = server.accept()
thread { serveFiles(directory.toString() + "/" + name, socket) }
thread { serveFiles(id, socket) }
}
}
.onFailure {
Log.ex(it)
server.close()
if (extensions.get(name)?.optInt("port") == port) {
extensions.get(name)!!.remove("port")
if (extensions.get(id)?.optInt("port") == port) {
extensions.get(id)!!.remove("port")
}
}
}
extensions.get(name)!!.put("port", server.getLocalPort())
extensions.get(id)!!.put("port", server.getLocalPort())
}
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/org/matrix/chromext/hook/Menu.kt
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ object MenuHook : BaseHook() {
}
when (ctx.resources.getResourceName(id)) {
"org.matrix.chromext:id/extension_id" -> {
Log.toast(ctx, "WIP support for extensions")
Log.toast(ctx, "Work in progress, might be ready in the future :)")
Listener.startAction("{action: 'extension'}")
}
"org.matrix.chromext:id/install_script_id" -> {
Expand Down

0 comments on commit 28f2779

Please sign in to comment.