Skip to content

Commit 93346d9

Browse files
Notplayingallday383illusionTBANovaAppsIncProgrammerIn-wonderland
committed
Initial Commit
Co-authored-by: illusionTBA <[email protected]> Co-authored-by: William Barnett <[email protected]> Co-authored-by: ProgrammerIn-wonderland <[email protected]>
0 parents  commit 93346d9

File tree

399 files changed

+63208
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

399 files changed

+63208
-0
lines changed

.github/ISSUE_TEMPLATE/bug-report.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
name: Bug report with a given code from the OS
3+
about: This should be used when the OS gives a Error Code and/or Error Message
4+
title: ''
5+
labels: bug
6+
assignees: NovaAppsInc, Notplayingallday383
7+
---
8+
9+
**Error Code and/or Error Message**
10+
Provide the Error Code and/or Error Message provided from the OS; it they required field should be copied to you clipboard if consented to it.
11+
12+
**Screenshots**
13+
If applicable, add screenshots to help explain your problem.
14+
15+
**OS Version and platform info**
16+
- Site you used [e.g. someterbiumrepl.repl.co]
17+
- Version (The latest version currently is v2.0, If in the About app it doesn't say v2.0 then consider updating your instance.)
18+
- Browser [e.g. Chrome, Firefox]
19+
20+
**Additional context**
21+
Add any other context about the problem here.

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
blank_issues_enabled: false
2+
default: bug-report.md

.github/dependabot.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "pnpm"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
day: "saturday"

.github/workflows/test.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Build Check
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
branches:
8+
- main
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
- name: Set up Node
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: 20
20+
- name: Install dependencies
21+
run: npm i
22+
- name: Build TB React
23+
run: npm run build

.gitignore

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
vite.config.ts.timestamp-*.mjs
10+
11+
node_modules
12+
dist
13+
dist-ssr
14+
*.local
15+
*.tsbuildinfo
16+
17+
# Editor directories and files
18+
.vscode/*
19+
!.vscode/extensions.json
20+
.idea
21+
.DS_Store
22+
*.suo
23+
*.ntvs*
24+
*.njsproj
25+
*.sln
26+
*.sw?
27+
.env
28+
29+
# Other
30+
src/apps.json
31+
src/hash.json
32+
src/installer.json

LICENSE.txt

Lines changed: 661 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<center>
2+
<img src="card.png" style="display: block; margin-left: auto; margin-right: auto; width: 300px;"></img>
3+
<h1 style="color: #32ae62;">Terbium v2 <i>React</i></h1>
4+
</center>
5+
6+
## <span style="color: #32ae62;">Some of the technologies used</span>
7+
8+
- [React](https://react.dev)
9+
- [TailwindCSS](https://tailwindcss.com)
10+
- [FilerJS](https://github.com/filerjs/filer)
11+
- [Fflate](https://github.com/101arrowz/fflate/)
12+
- [BareMux](https://github.com/mercuryworkshop/bare-mux)
13+
14+
## <span style="color: #32ae62;">Features</span>
15+
16+
- All new UI
17+
- A Dynamic Shell
18+
- Better Window Manager
19+
- A desktop
20+
- App Store
21+
- A brand new terminal
22+
- Anura Compatability layer (Liquor)
23+
- And lots more!
24+
25+
## <span style="color: #32ae62;">Setup</span>
26+
27+
To get started its pretty easy you need either npm or pnpm which can be installed by running: `npm i -g pnpm` and then just need to the run following command
28+
29+
```bash
30+
pnpm i && pnpm start # Replace pnpm with npm if your not going to use pnpm
31+
```
32+
33+
and visit [http://localhost:3000](http://localhost:3000) you should be good to go!
34+
35+
If you are developing/modifying terbium you can just run `pnpm run dev`, **DO NOT** use the development server for Production use instead just run `pnpm start`. For any further backend configuration visit the `.env` file to configure the backend a bit.
36+
37+
> <span style="font-family: none; color: #ffd900;">⚠</span> <span style="color: #ffd900;">Warning</span><br>
38+
> If you are going to static host Terbium you will need to change the wisp server and you would need to follow those steps. Refer to this [document](./docs/static-hosting.md) for more information
39+
40+
### <span style="color: #32ae62;">Documentation</span>
41+
42+
If you wish to develop or just learn more about terbiums components and stuff feel free to read out [Documentation](/docs/README.md)
43+
44+
If your looking to see what Anura APIs and features are supported in terbium, refer to: [here](/docs/anura-compat.md)
45+
46+
### <span style="color: #32ae62;">Contributors</span>
47+
48+
- [SNOOT](https://github.com/NovaAppsInc)
49+
- [XSTARS](https://github.com/Notplayingallday383)
50+
- [illusionTBA](https://github.com/illusionTBA)
51+
- [Rafflesia](https://github.com/ProgrammerIn-wonderland)
52+
- [Riftriot](https://github.com/Riftriot)
53+
54+
Licensed under the [**AGPL3 License**](https://www.gnu.org/licenses/agpl-3.0.en.html)

SECURITY.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Security Policy
2+
3+
### Supported Versions
4+
5+
| Version | Supported |
6+
| ------- | --------- |
7+
| 2.0.0 ||
8+
9+
## Reporting a Vulnerability
10+
11+
In the case that you somehow manage to find a vulnerability in Terbium please contact [email protected]
12+
13+
REMEMBER: Please DO NOT report vulnerabilities in the repository Issues tab.
14+
15+
## What You Should Report
16+
17+
If you are wondering what counts as a vulnerability, heres a good list:
18+
19+
- XSS in the URL your using
20+
- The ability to execute malicious code on the server hosting Terbium
21+
- Any kind of leak of data/information in the code

bootstrap.ts

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import fs from "fs";
2+
import path from "path";
3+
import { fileURLToPath } from "url";
4+
import consola from "consola";
5+
import { TServer } from "./server";
6+
import { version } from "./package.json";
7+
import open from "open";
8+
import { exec } from "child_process";
9+
10+
consola.info("Bootstrapping TerbiumOS [v" + version + "]");
11+
12+
export default async function Bootstrap() {
13+
const args = process.argv
14+
await BuildApps();
15+
await CreateAppsPaths();
16+
if (!fs.existsSync(".env")) await CreateEnv();
17+
await Updater();
18+
consola.success("TerbiumOS bootstrapped successfully");
19+
if (!(args.includes("--apps-only") || args.includes("--dev"))) {
20+
TServer();
21+
}
22+
}
23+
24+
export async function BuildApps() {
25+
consola.start("Building apps...");
26+
const __dirname = path.dirname(fileURLToPath(import.meta.url)),
27+
baseDir = path.join(__dirname, "./public/apps"),
28+
outputDir = path.join(__dirname, "./src"),
29+
outputJsonPath = path.join(outputDir, "apps.json"),
30+
result: { name: string; config: any }[] = [];
31+
function scanDirectory(dir: string) {
32+
fs.readdirSync(dir, { withFileTypes: true }).forEach((i) => {
33+
if (i.isDirectory()) {
34+
const indexFilePath = path.join(dir, i.name, "index.json");
35+
if (fs.existsSync(indexFilePath)) {
36+
try {
37+
const data = JSON.parse(fs.readFileSync(indexFilePath, "utf-8"));
38+
if (data.name && data.config) {
39+
if (data.name !== "Browser") {
40+
data.config.src = data.config.src.replace(`/apps/${data.name.toLowerCase()}.tapp/`, `/fs/apps/system/${data.name.toLowerCase()}.tapp/`);
41+
data.config.icon = data.config.icon.replace(`/apps/${data.name.toLowerCase()}.tapp/`, `/fs/apps/system/${data.name.toLowerCase()}.tapp/`);
42+
} else {
43+
return;
44+
}
45+
result.push({ name: data.name, config: data.config });
46+
}
47+
} catch (t) {
48+
consola.error(`Error parsing ${indexFilePath}:`, t.message);
49+
}
50+
}
51+
}
52+
});
53+
}
54+
scanDirectory(baseDir),
55+
fs.existsSync(path.join(__dirname, "./build")) || fs.mkdirSync(path.join(__dirname, "./build")),
56+
fs.existsSync(outputJsonPath) || fs.writeFileSync(outputJsonPath, "[]", "utf-8"),
57+
fs.writeFileSync(outputJsonPath, JSON.stringify(result, null, 2), "utf-8"),
58+
consola.success(`Aggregated JSON saved to ${outputJsonPath}`);
59+
exec("git rev-parse HEAD", (error, stdout, stderr) => {
60+
if (error || stderr) {
61+
consola.error("Failed to get git commit hash");
62+
} else {
63+
const hash = stdout.trim();
64+
exec("git remote get-url origin", (remoteError, remoteStdout, remoteStderr) => {
65+
const repoUrl = remoteStdout.trim();
66+
const data = { hash, repository: repoUrl.replace("https://github.com/", "") };
67+
if (remoteError || remoteStderr) {
68+
consola.error("Failed to get repository URL");
69+
fs.writeFileSync(path.join(__dirname, "./src/hash.json"), JSON.stringify({ hash: null, repository: null}, null, 2), "utf-8");
70+
} else {
71+
fs.writeFileSync(path.join(__dirname, "./src/hash.json"), JSON.stringify(data, null, 2), "utf-8");
72+
consola.success(`Git hash and repo saved to ${path.join(__dirname, "./src/hash.json")}`);
73+
}
74+
});
75+
}
76+
});
77+
}
78+
79+
export async function CreateAppsPaths() {
80+
interface Apps {
81+
[appName: string]: (string | { [path: string]: string[] })[];
82+
}
83+
consola.start("Creating apps paths...");
84+
85+
const __dirname = path.dirname(fileURLToPath(import.meta.url)),
86+
baseDir = path.join(__dirname, "./public/apps"),
87+
outputDir = path.join(__dirname, "./src"),
88+
outputJsonPath = path.join(outputDir, "installer.json"),
89+
output: string[] = [];
90+
91+
function collectPaths(dir: string, base: string = dir): void {
92+
const files: fs.Dirent[] = fs.readdirSync(dir, { withFileTypes: true });
93+
files.forEach((file: fs.Dirent) => {
94+
const fullPath = path.join(dir, file.name);
95+
const relativePath = path.relative(baseDir, fullPath).replace(/\\/g, "/");
96+
if (file.isDirectory()) {
97+
output.push(relativePath + "/");
98+
collectPaths(fullPath, base);
99+
} else {
100+
output.push(relativePath);
101+
}
102+
});
103+
}
104+
105+
const accmp: string[] = [];
106+
fs.readdirSync(baseDir, { withFileTypes: true }).forEach(app => {
107+
if (app.isDirectory() && app.name.toLocaleLowerCase().endsWith(".tapp") && !app.name.toLowerCase().includes("browser.tapp")) {
108+
const appPath = path.join(baseDir, app.name);
109+
if (app.name.toLowerCase() === "settings.tapp") {
110+
collectPaths(appPath);
111+
if (fs.existsSync(path.join(appPath, "accounts"))) {
112+
collectPaths(path.join(appPath, "accounts"));
113+
accmp.push(...output.splice(output.indexOf("settings.tapp/accounts/")));
114+
}
115+
} else {
116+
collectPaths(appPath);
117+
}
118+
}
119+
});
120+
121+
output.push(...accmp);
122+
fs.writeFileSync(outputJsonPath, JSON.stringify(output, null, 2), "utf-8");
123+
consola.success(`Installer JSON saved to ${outputJsonPath}`);
124+
}
125+
126+
export async function CreateEnv() {
127+
const port = await consola.prompt("Enter a port for the server to run on (3000): ", {
128+
type: "text",
129+
default: "3000",
130+
placeholder: "3000",
131+
cancel: "default",
132+
}) || 3000;
133+
const masqr = await consola.prompt("Enable Masqr? (no): ", {
134+
type: "text",
135+
default: "false",
136+
placeholder: "no",
137+
cancel: "default",
138+
});
139+
if(masqr === "no" || masqr === "false" || masqr === "n") {
140+
fs.writeFileSync(".env", `MASQR=${false}\nPORT=${port}`);
141+
} else {
142+
const licenseServer = await consola.prompt("Enter the masqr license server URL: ") || "";
143+
const whitelist = await consola.prompt("Enter a comma separated array of domains to whitelist (Ex: ['https://balls.com', 'https://tomp.app']): ") || [];
144+
fs.writeFileSync(".env", `MASQR=${true}\nPORT=${port}\nLICENSE_SERVER_URL=${licenseServer}\nWHITELISTED_DOMAINS=${whitelist}\n`);
145+
}
146+
consola.success("Environment file created");
147+
}
148+
149+
export async function Updater() {
150+
consola.start("Checking for updates...");
151+
exec("git remote get-url origin", async (remoteError, remoteStdout, remoteStderr) => {
152+
if (remoteError || remoteStderr) {
153+
consola.error("Failed to get local repository URL");
154+
return;
155+
}
156+
const repo = `https://raw.githubusercontent.com/${remoteStdout.trim().replace("https://github.com/", "")}/refs/heads/main/package.json` || "https://raw.githubusercontent.com/TerbiumOS/web-react/refs/heads/main/package.json";
157+
try {
158+
const response = await fetch(repo);
159+
const ver = (await response.json()).version;
160+
if (ver !== version) {
161+
const res = await consola.prompt(`A new version of Terbium is available. Would you like to download it? (New Version: ${ver}, Current: ${version})`, {
162+
type: "confirm"
163+
});
164+
if (res) {
165+
open(`${remoteStdout.trim()}/releases/latest`);
166+
return;
167+
} else return;
168+
} else {
169+
consola.success("Terbium is up to date");
170+
}
171+
} catch (e) {
172+
consola.error(`Failed to check for updates, ${e}`);
173+
}
174+
});
175+
}
176+
177+
Bootstrap();

card.png

479 KB
Loading

0 commit comments

Comments
 (0)