Skip to content

Commit c3aedd9

Browse files
move token logic of auth.js to native
1 parent 32a2838 commit c3aedd9

File tree

8 files changed

+331
-153
lines changed

8 files changed

+331
-153
lines changed

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"cordova-plugin-system": {},
4040
"com.foxdebug.acode.rk.exec.proot": {},
4141
"com.foxdebug.acode.rk.exec.terminal": {},
42-
"com.foxdebug.acode.rk.customtabs": {}
42+
"com.foxdebug.acode.rk.customtabs": {},
43+
"com.foxdebug.acode.rk.auth": {}
4344
},
4445
"platforms": [
4546
"android"
@@ -64,6 +65,7 @@
6465
"@types/url-parse": "^1.4.11",
6566
"autoprefixer": "^10.4.21",
6667
"babel-loader": "^10.0.0",
68+
"com.foxdebug.acode.rk.auth": "file:src/plugins/auth",
6769
"com.foxdebug.acode.rk.customtabs": "file:src/plugins/custom-tabs",
6870
"com.foxdebug.acode.rk.exec.proot": "file:src/plugins/proot",
6971
"com.foxdebug.acode.rk.exec.terminal": "file:src/plugins/terminal",

src/components/sidebar/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ function create($container, $toggler) {
489489
$el.show = show;
490490
$el.hide = hide;
491491
$el.toggle = toggle;
492-
$el.onshow = () => {};
492+
$el.onshow = () => { };
493493
$el.getWidth = function () {
494494
const width = innerWidth * 0.7;
495495
return mode === "phone" ? (width >= 350 ? 350 : width) : MIN_WIDTH;

src/lib/auth.js

Lines changed: 61 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import fsOperation from "fileSystem";
21
import toast from "components/toast";
32
import { addIntentHandler } from "handlers/intent";
4-
import constants from "./constants";
53

64
const loginEvents = {
75
listeners: new Set(),
@@ -18,70 +16,16 @@ const loginEvents = {
1816
},
1917
};
2018

21-
async function checkTokenFileExists() {
22-
return await fsOperation(`${DATA_STORAGE}.acode_token`).exists();
23-
}
24-
25-
async function saveToken(token) {
26-
try {
27-
if (await checkTokenFileExists()) {
28-
await fsOperation(`${DATA_STORAGE}.acode_token`).writeFile(token);
29-
} else {
30-
await fsOperation(DATA_STORAGE).createFile(".acode_token", token);
31-
}
32-
return true;
33-
} catch (error) {
34-
console.error("Failed to save token", error);
35-
return false;
36-
}
37-
}
38-
39-
async function getToken() {
40-
try {
41-
if (await checkTokenFileExists()) {
42-
const token = await fsOperation(`${DATA_STORAGE}.acode_token`).readFile(
43-
"utf8",
44-
);
45-
return token;
46-
}
47-
return null;
48-
} catch (error) {
49-
console.error("Failed to get token", error);
50-
return null;
51-
}
52-
}
53-
54-
async function deleteToken() {
55-
try {
56-
if (await checkTokenFileExists()) {
57-
await fsOperation(`${DATA_STORAGE}.acode_token`).delete();
58-
return true;
59-
}
60-
return false;
61-
} catch (error) {
62-
console.error("Failed to delete token", error);
63-
return false;
64-
}
65-
}
66-
6719
class AuthService {
6820
constructor() {
6921
addIntentHandler(this.onIntentReceiver.bind(this));
7022
}
7123

72-
openLoginUrl() {
73-
try {
74-
system.openInBrowser("https://acode.app/login?redirect=app");
75-
} catch (error) {
76-
console.error("Failed while opening login page.", error);
77-
}
78-
}
79-
8024
async onIntentReceiver(event) {
8125
try {
8226
if (event?.module === "user" && event?.action === "login") {
8327
if (event?.value) {
84-
saveToken(event.value);
28+
this._exec("saveToken", [event.value]);
8529
toast("Logged in successfully");
8630

8731
setTimeout(() => {
@@ -96,10 +40,28 @@ class AuthService {
9640
}
9741
}
9842

43+
/**
44+
* Helper to wrap cordova.exec in a Promise
45+
*/
46+
_exec(action, args = []) {
47+
return new Promise((resolve, reject) => {
48+
cordova.exec(resolve, reject, "Authenticator", action, args);
49+
});
50+
}
51+
52+
openLoginUrl() {
53+
try {
54+
//todo use Custom tabs api for better ux
55+
system.openInBrowser("https://acode.app/login?redirect=app");
56+
} catch (error) {
57+
console.error("Failed while opening login page.", error);
58+
}
59+
}
60+
9961
async logout() {
10062
try {
101-
const result = await deleteToken();
102-
return result;
63+
await this._exec("logout");
64+
return true;
10365
} catch (error) {
10466
console.error("Failed to logout.", error);
10567
return false;
@@ -108,69 +70,19 @@ class AuthService {
10870

10971
async isLoggedIn() {
11072
try {
111-
const token = await getToken();
112-
if (!token) return false;
113-
114-
return new Promise((resolve, reject) => {
115-
cordova.plugin.http.sendRequest(
116-
`${constants.API_BASE}/login`,
117-
{
118-
method: "GET",
119-
headers: {
120-
"x-auth-token": token,
121-
},
122-
},
123-
(response) => {
124-
resolve(true);
125-
},
126-
async (error) => {
127-
if (error.status === 401) {
128-
await deleteToken();
129-
resolve(false);
130-
} else {
131-
console.error("Failed to check login status.", error);
132-
resolve(false);
133-
}
134-
},
135-
);
136-
});
73+
// Native checks EncryptedPrefs and validates with API internally
74+
await this._exec("isLoggedIn");
75+
return true;
13776
} catch (error) {
138-
console.error("Failed to check login status.", error);
77+
// error is typically the status code (0 if no token, 401 if invalid)
13978
return false;
14079
}
14180
}
14281

14382
async getUserInfo() {
14483
try {
145-
const token = await getToken();
146-
if (!token) return null;
147-
148-
return new Promise((resolve, reject) => {
149-
cordova.plugin.http.sendRequest(
150-
`${constants.API_BASE}/login`,
151-
{
152-
method: "GET",
153-
headers: {
154-
"x-auth-token": token,
155-
},
156-
},
157-
async (response) => {
158-
if (response.status === 200) {
159-
resolve(JSON.parse(response.data));
160-
}
161-
resolve(null);
162-
},
163-
async (error) => {
164-
if (error.status === 401) {
165-
await deleteToken();
166-
resolve(null);
167-
} else {
168-
console.error("Failed to fetch user data.", error);
169-
resolve(null);
170-
}
171-
},
172-
);
173-
});
84+
const data = await this._exec("getUserInfo");
85+
return typeof data === "string" ? JSON.parse(data) : data;
17486
} catch (error) {
17587
console.error("Failed to fetch user data.", error);
17688
return null;
@@ -180,49 +92,15 @@ class AuthService {
18092
async getAvatar() {
18193
try {
18294
const userData = await this.getUserInfo();
95+
console.log(userData);
18396
if (!userData) return null;
18497

18598
if (userData.github) {
18699
return `https://avatars.githubusercontent.com/${userData.github}`;
187100
}
188101

189102
if (userData.name) {
190-
const nameParts = userData.name.split(" ");
191-
let initials = "";
192-
193-
if (nameParts.length >= 2) {
194-
initials = `${nameParts[0][0]}${nameParts[1][0]}`.toUpperCase();
195-
} else {
196-
initials = nameParts[0][0].toUpperCase();
197-
}
198-
199-
// Create a data URL for text-based avatar
200-
const canvas = document.createElement("canvas");
201-
canvas.width = 100;
202-
canvas.height = 100;
203-
const ctx = canvas.getContext("2d");
204-
205-
// Set background
206-
// Array of colors to choose from
207-
const colors = [
208-
"#2196F3",
209-
"#9C27B0",
210-
"#E91E63",
211-
"#009688",
212-
"#4CAF50",
213-
"#FF9800",
214-
];
215-
ctx.fillStyle = colors[Math.floor(Math.random() * colors.length)];
216-
ctx.fillRect(0, 0, 100, 100);
217-
218-
// Add text
219-
ctx.fillStyle = "#ffffff";
220-
ctx.font = "bold 40px Arial";
221-
ctx.textAlign = "center";
222-
ctx.textBaseline = "middle";
223-
ctx.fillText(initials, 50, 50);
224-
225-
return canvas.toDataURL();
103+
return this._generateInitialsAvatar(userData.name);
226104
}
227105

228106
return null;
@@ -231,6 +109,38 @@ class AuthService {
231109
return null;
232110
}
233111
}
112+
113+
_generateInitialsAvatar(name) {
114+
const nameParts = name.split(" ");
115+
const initials =
116+
nameParts.length >= 2
117+
? `${nameParts[0][0]}${nameParts[1][0]}`.toUpperCase()
118+
: nameParts[0][0].toUpperCase();
119+
120+
const canvas = document.createElement("canvas");
121+
canvas.width = 100;
122+
canvas.height = 100;
123+
const ctx = canvas.getContext("2d");
124+
125+
const colors = [
126+
"#2196F3",
127+
"#9C27B0",
128+
"#E91E63",
129+
"#009688",
130+
"#4CAF50",
131+
"#FF9800",
132+
];
133+
ctx.fillStyle = colors[Math.floor(Math.random() * colors.length)];
134+
ctx.fillRect(0, 0, 100, 100);
135+
136+
ctx.fillStyle = "#ffffff";
137+
ctx.font = "bold 40px Arial";
138+
ctx.textAlign = "center";
139+
ctx.textBaseline = "middle";
140+
ctx.fillText(initials, 50, 50);
141+
142+
return canvas.toDataURL();
143+
}
234144
}
235145

236146
export default new AuthService();

src/plugins/auth/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "com.foxdebug.acode.rk.auth",
3+
"version": "1.0.0",
4+
"description": "Authentication plugin",
5+
"cordova": {
6+
"id": "com.foxdebug.acode.rk.auth",
7+
"platforms": [
8+
"android"
9+
]
10+
},
11+
"keywords": [
12+
"ecosystem:cordova",
13+
"cordova-android"
14+
],
15+
"author": "@RohitKushvaha01",
16+
"license": "MIT"
17+
}

src/plugins/auth/plugin.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="com.foxdebug.acode.rk.auth" version="1.0.0">
3+
<name>Authentication</name>
4+
5+
6+
<platform name="android">
7+
<config-file parent="/*" target="res/xml/config.xml">
8+
<feature name="Authenticator">
9+
<param name="android-package" value="com.foxdebug.acode.rk.auth.Authenticator" />
10+
</feature>
11+
</config-file>
12+
13+
<framework src="androidx.security:security-crypto:1.1.0" />
14+
15+
<source-file src="src/android/Authenticator.java" target-dir="src/com/foxdebug/acode/rk/auth" />
16+
<source-file src="src/android/EncryptedPreferenceManager.java" target-dir="src/com/foxdebug/acode/rk/auth" />
17+
18+
19+
</platform>
20+
</plugin>

0 commit comments

Comments
 (0)