Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add activation #194

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
<script type="text/javascript" src="lib/api/Files.js"></script>
<script type="text/javascript" src="lib/api/UI.js"></script>
<script type="text/javascript" src="lib/Anura.js"></script>
<script type="text/javascript" src="lib/Activation.js"></script>
<script type="text/javascript" src="lib/api/Settings.js"></script>
<script
type="text/javascript"
Expand Down
48 changes: 48 additions & 0 deletions src/Activation.ts
wearrrrr marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class Activation {
constructor(settings: Settings = anura.settings) {
this.activated =
settings.get("product-key") !== undefined &&
this.validate(settings.get("product-key"));
}

activated: boolean;

validate(key: string): boolean {
// Split the key into parts based on the hyphen
const parts = key.split("-");
if (parts.length !== 2) return false;

const prefix = parts[0];
const suffix = parts[1];

// Validate prefix: 3 digits, not starting with '0'
if (
!prefix ||
prefix?.length !== 3 ||
isNaN(Number(prefix)) ||
prefix.startsWith("0")
)
return false;

// Validate suffix: 7 digits
if (!suffix || suffix?.length !== 7 || isNaN(Number(suffix)))
return false;

// Calculate sum of digits in the suffix
let sum = 0;
for (let i = 0; i < suffix.length; i++) {
sum += parseInt(suffix![i]!, 10);
}

// The sum of the digits should be divisible by 7
const res = sum % 7 === 0;
console.log(res);
return res;
}

refreshActivationState() {
this.activated =
anura.settings.get("product-key") !== undefined &&
this.validate(anura.settings.get("product-key"));
}
}
2 changes: 2 additions & 0 deletions src/Anura.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Anura {
dialog: Dialog;
sw: SWProcess;
anurad: Anurad;
activation: Activation;
systray: Systray;
uri = new URIHandlerAPI();
files = new FilesAPI();
Expand All @@ -49,6 +50,7 @@ class Anura {

this.notifications = new NotificationService();
this.processes = new Processes();
this.activation = new Activation(settings);
document.body.appendChild(this.notifications.element);
}

Expand Down
15 changes: 15 additions & 0 deletions src/Boot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,20 @@ window.addEventListener("load", async () => {
} else if (anura.settings.get("i-am-a-true-gangsta")) {
splashToRemove = gangstaBootsplash;
document.body.appendChild(gangstaBootsplash);
} else if (anura.activation.activated === false) {
splashToRemove = bootsplash;
document.body.appendChild(bootsplash);
const ActivateMark = document.createElement("span");
ActivateMark.setAttribute(
"style",
"position: absolute; bottom: 70px; right: 30px; color: white; opacity: 0.8; z-index: 99999999; user-select: none; webkit-user-select: none; pointer-events: none;",
);
ActivateMark.innerHTML =
"<h2 style='margin-bottom: 0;'>Activate AnuraOS</h2><p style='margin-top: 0.5rem;'>Open Settings to activate AnuraOS.</p>";
// ActivateMark.onclick = () => {
// anura.apps["anura.settings"].open();
// }
document.body.appendChild(ActivateMark);
} else {
splashToRemove = bootsplash;
document.body.appendChild(bootsplash);
Expand Down Expand Up @@ -609,6 +623,7 @@ document.addEventListener("anura-login-completed", async () => {
document.body.appendChild(quickSettings.notificationCenterElement);
document.body.appendChild(taskbar.element);
document.body.appendChild(alttab.element);

anura.systray = new Systray();
AnuradHelpers.setReady("anura.systray");

Expand Down
47 changes: 47 additions & 0 deletions src/coreapps/SettingsApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,52 @@ class SettingsApp extends App {
>
<div id="general" class="general settings-category">
<h3 class="settings-category-name">General</h3>
{!anura.activation.activated ? (
<div>
<div class="settings-group">
<button
class="matter-button-contained"
on:click={async () => {
const key = await anura.dialog.prompt(
"Enter your product key",
);

if (
anura.activation.validate(key)
) {
anura.settings.set(
"product-key",
key,
);
anura.activation.refreshActivationState();
anura.notifications.add({
title: "Product key activated",
description:
"AnuraOS has been activated with the provided key. Restarting in 5 seconds...",
timeout: 5000,
});
setTimeout(() => {
window.location.reload();
}, 5000);
} else {
anura.notifications.add({
title: "Invalid product key",
description:
"The provided product key is invalid",
timeout: 5000,
});
}
}}
>
Activate AnuraOS
</button>
</div>

<br></br>
</div>
) : (
<div></div>
)}
<div class="settings-group">
<SettingSwitch
title="Allow offline use"
Expand Down Expand Up @@ -370,6 +416,7 @@ class SettingsApp extends App {
{this.state.show_x86_install ? (
<div>
<button
disabled={!anura.activation.activated}
on:click={async () => {
this.state.x86_installing = true;
anura.settings.set(
Expand Down
130 changes: 128 additions & 2 deletions src/oobe/OobeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ class OobeView {
offlineEnabled: true,
v86Enabled: false,
dlsize: "0MB",
productKey: "",
});

activation = new Activation();

constructor() {
useChange([this.state.offlineEnabled, this.state.v86Enabled], () => {
this.state.dlsize = "0MB";
Expand Down Expand Up @@ -105,6 +108,18 @@ class OobeView {
filter: brightness(1.1);
}

.screen .unpreferredButton {
background-color: transparent;
border: 1px solid rgb(26, 115, 232);
border-radius: 16px;
border-style: none;
color: white;
height: 2em;
padding-left: 1em;
padding-right: 1em;
transition: 0s;
}

.screen button {
background-color: var(--oobe-bg);
border-radius: 16px;
Expand Down Expand Up @@ -134,6 +149,10 @@ class OobeView {
display: ${anura.platform.type === "mobile" ? "none;" : "unset;"};
}

#activation #subtitle {
margin-bottom: 0.25rem;
}

.material-symbols-outlined {
font-size: 1rem;
}
Expand All @@ -151,6 +170,15 @@ class OobeView {
#features #subtitle {
margin-bottom: 2rem;
}

.matter-textfield-standard > input,
.matter-textfield-standard > textarea {
border-bottom: solid 1px gray;
}

.matter-checkbox:has(input:disabled) {
filter: grayscale(1) contrast(0.25);
}
`;

steps = [
Expand All @@ -174,6 +202,101 @@ class OobeView {
),
on: () => {},
},

{
elm: (
<div class="screen" id="activation">
<h1>Activate AnuraOS</h1>
<div id="subtitle">
Locate your 10-digit product key and type it in the
space below. Then click Next to continue.
</div>
<div id="gridContent">
<div>
<label class="matter-textfield-standard">
<input
placeholder=" "
type="text"
pattern="[0-9]{3}-[0-9]{7}"
bind:value={use(this.state.productKey)}
on:keypress={() => {
if (this.state.productKey.length > 11) {
this.state.productKey =
this.state.productKey.slice(
0,
11,
);
} else if (
this.state.productKey.length === 3
) {
this.state.productKey += "-";
}
}}
/>
<span>Product Key</span>
</label>
<br></br>
<div
class="sub"
style={{
marginTop: "1rem",
}}
>
<span class="material-symbols-outlined">
info
</span>
&nbsp;Any Windows 95 retail key will work.
</div>
</div>
<div id="bottomButtons">
<button on:click={() => this.nextStep()}>
I don't have a key
</button>
<button
on:click={() => {
try {
// The sum of the digits should be divisible by 7
if (
this.activation.validate(
this.state.productKey,
)
) {
anura.settings.set(
"product-key",
this.state.productKey,
);
this.nextStep();
} else {
throw "Invalid key!";
}
} catch (e) {
console.error(e);
alert(
"Invalid key! Please check the key and try again.",
);
}
}}
class="preferredButton"
>
<div
style={{
display: "flex",
alignItems: "center",
fontSize: "0.7rem!important",
}}
>
<span>Next</span>
<span class="material-symbols-outlined">
chevron_right
</span>
</div>
</button>
</div>
</div>
</div>
),
on: () => {},
},
{
elm: (
<div class="screen" id="features">
Expand All @@ -196,13 +319,16 @@ class OobeView {
<input
type="checkbox"
bind:checked={use(this.state.v86Enabled)}
disabled={!this.activation.activated}
/>
<span>Linux Emulation</span>
</label>
<div class="sub">
<span class="material-symbols-outlined">info</span>
&nbsp;This allows you to run Linux applications on
AnuraOS.
&nbsp;
{this.activation.activated
? "This allows you to run Linux applications on AnuraOS."
: "The x86 subsystem is not available because you have not activated AnuraOS."}
</div>
<br></br>
<div id="size" class="sub">
Expand Down