@leadertechie/personal-site-kit 0.1.0-alpha.4 → 0.1.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/handlers/auth-handler.d.ts +2 -0
- package/dist/api/handlers/auth-handler.d.ts.map +1 -0
- package/dist/api/handlers/auth.d.ts +23 -0
- package/dist/api/handlers/auth.d.ts.map +1 -0
- package/dist/api/handlers/content.d.ts.map +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/website-api.d.ts +1 -1
- package/dist/api/website-api.d.ts.map +1 -1
- package/dist/api.js +17 -2
- package/dist/chunks/{index-VimKeB5W.js → index-C3wLSCKU.js} +236 -93
- package/dist/chunks/{website-api-CVsi-OLc.js → website-api-DI3muo2s.js} +335 -23
- package/dist/index.js +27 -13
- package/dist/ui/admin/index.d.ts +12 -3
- package/dist/ui/admin/index.d.ts.map +1 -1
- package/dist/ui.js +1 -1
- package/package.json +1 -1
- package/src/api/handlers/auth-handler.ts +181 -0
- package/src/api/handlers/auth.ts +157 -0
- package/src/api/handlers/content.ts +81 -14
- package/src/api/index.ts +2 -0
- package/src/api/website-api.ts +22 -16
- package/src/ui/admin/index.ts +254 -91
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/auth-handler.ts"],"names":[],"mappings":"AAkBA,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkC/F"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare const AUTH_KV = "auth_store";
|
|
2
|
+
declare const RATE_LIMIT_KV = "rate_limit";
|
|
3
|
+
declare const MAX_ATTEMPTS = 5;
|
|
4
|
+
declare const BASE_DELAY_MS = 1000;
|
|
5
|
+
interface AuthStore {
|
|
6
|
+
username: string;
|
|
7
|
+
passwordHash: string;
|
|
8
|
+
salt: string;
|
|
9
|
+
}
|
|
10
|
+
declare function hashPassword(password: string, salt: string): Promise<string>;
|
|
11
|
+
declare function generateSalt(): Promise<string>;
|
|
12
|
+
declare function checkRateLimit(env: any, ip: string): Promise<{
|
|
13
|
+
allowed: boolean;
|
|
14
|
+
delayMs: number;
|
|
15
|
+
}>;
|
|
16
|
+
declare function recordFailedAttempt(env: any, ip: string): Promise<void>;
|
|
17
|
+
declare function clearRateLimit(env: any, ip: string): Promise<void>;
|
|
18
|
+
declare function getAuthStore(env: any): Promise<AuthStore | null>;
|
|
19
|
+
declare function setupAuth(env: any, username: string, password: string): Promise<void>;
|
|
20
|
+
declare function verifyCredentials(env: any, username: string, password: string): Promise<boolean>;
|
|
21
|
+
declare function getClientIP(request: Request): string;
|
|
22
|
+
export { hashPassword, generateSalt, checkRateLimit, recordFailedAttempt, clearRateLimit, getAuthStore, setupAuth, verifyCredentials, getClientIP, AUTH_KV, RATE_LIMIT_KV, MAX_ATTEMPTS, BASE_DELAY_MS };
|
|
23
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/auth.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,OAAO,eAAe,CAAC;AAC7B,QAAA,MAAM,aAAa,eAAe,CAAC;AACnC,QAAA,MAAM,YAAY,IAAI,CAAC;AACvB,QAAA,MAAM,aAAa,OAAO,CAAC;AAG3B,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAQD,iBAAe,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB3E;AAED,iBAAe,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAG7C;AAED,iBAAe,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA2BlG;AAED,iBAAe,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBtE;AAED,iBAAe,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjE;AAED,iBAAe,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAG/D;AAED,iBAAe,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASpF;AAED,iBAAe,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAa/F;AAED,iBAAS,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAI7C;AAED,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,OAAO,EACP,aAAa,EACb,YAAY,EACZ,aAAa,EACd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/content.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/content.ts"],"names":[],"mappings":"AAkBA,wBAAsB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAiElG"}
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { WebsiteAPI } from './website-api';
|
|
2
2
|
export { WebsiteAPI };
|
|
3
3
|
export type { APIHandler } from './website-api';
|
|
4
|
+
export * from './handlers/auth';
|
|
5
|
+
export * from './handlers/auth-handler';
|
|
4
6
|
declare const defaultAPI: WebsiteAPI;
|
|
5
7
|
export default defaultAPI;
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AAGxC,QAAA,MAAM,UAAU,YAAmB,CAAC;AACpC,eAAe,UAAU,CAAC"}
|
|
@@ -3,8 +3,8 @@ export declare class WebsiteAPI {
|
|
|
3
3
|
private customHandlers;
|
|
4
4
|
registerHandler(route: string, handler: APIHandler): void;
|
|
5
5
|
private addCORSHeaders;
|
|
6
|
+
private addAdminCORSHeaders;
|
|
6
7
|
private handleCORS;
|
|
7
|
-
private requireAuth;
|
|
8
8
|
fetch(request: Request, env: any): Promise<Response>;
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=website-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"website-api.d.ts","sourceRoot":"","sources":["../../src/api/website-api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"website-api.d.ts","sourceRoot":"","sources":["../../src/api/website-api.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE3E,qBAAa,UAAU;IACrB,OAAO,CAAC,cAAc,CAAiC;IAEhD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;IAIzD,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,UAAU;IAYL,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;CAkFlE"}
|
package/dist/api.js
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
import { W as WebsiteAPI } from "./chunks/website-api-
|
|
1
|
+
import { W as WebsiteAPI } from "./chunks/website-api-DI3muo2s.js";
|
|
2
|
+
import { A, B, M, R, c, a, g, b, d, h, e, r, s, v } from "./chunks/website-api-DI3muo2s.js";
|
|
2
3
|
const defaultAPI = new WebsiteAPI();
|
|
3
4
|
export {
|
|
5
|
+
A as AUTH_KV,
|
|
6
|
+
B as BASE_DELAY_MS,
|
|
7
|
+
M as MAX_ATTEMPTS,
|
|
8
|
+
R as RATE_LIMIT_KV,
|
|
4
9
|
WebsiteAPI,
|
|
5
|
-
|
|
10
|
+
c as checkRateLimit,
|
|
11
|
+
a as clearRateLimit,
|
|
12
|
+
defaultAPI as default,
|
|
13
|
+
g as generateSalt,
|
|
14
|
+
b as getAuthStore,
|
|
15
|
+
d as getClientIP,
|
|
16
|
+
h as handleAuth,
|
|
17
|
+
e as hashPassword,
|
|
18
|
+
r as recordFailedAttempt,
|
|
19
|
+
s as setupAuth,
|
|
20
|
+
v as verifyCredentials
|
|
6
21
|
};
|
|
@@ -564,38 +564,151 @@ var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "rea
|
|
|
564
564
|
var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$4("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
565
565
|
var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
566
566
|
var __privateMethod$3 = (obj, member, method) => (__accessCheck$3(obj, member, "access private method"), method);
|
|
567
|
-
var _staticDetails_dec, _activeSection_dec, _statusMessage_dec, _contentList_dec,
|
|
568
|
-
console.log("[AdminPortal] Module loading");
|
|
569
|
-
console.log("[AdminPortal] About to define custom element");
|
|
567
|
+
var _loginError_dec, _staticDetails_dec, _activeSection_dec, _statusMessage_dec, _contentList_dec, _isLoading_dec, _isSetup_dec, _isAuthenticated_dec, _a$4, _AdminPortal_decorators, _init$4, _isAuthenticated, _isSetup, _isLoading, _contentList, _statusMessage, _activeSection, _staticDetails, _loginError;
|
|
570
568
|
_AdminPortal_decorators = [customElement("admin-portal")];
|
|
571
|
-
class AdminPortal extends (_a$4 = LitElement,
|
|
569
|
+
class AdminPortal extends (_a$4 = LitElement, _isAuthenticated_dec = [state()], _isSetup_dec = [state()], _isLoading_dec = [state()], _contentList_dec = [state()], _statusMessage_dec = [state()], _activeSection_dec = [state()], _staticDetails_dec = [state()], _loginError_dec = [state()], _a$4) {
|
|
572
570
|
constructor() {
|
|
573
571
|
super(...arguments);
|
|
574
|
-
__privateAdd$3(this,
|
|
575
|
-
__privateAdd$3(this,
|
|
576
|
-
__privateAdd$3(this,
|
|
577
|
-
__privateAdd$3(this,
|
|
578
|
-
__privateAdd$3(this,
|
|
579
|
-
__privateAdd$3(this,
|
|
572
|
+
__privateAdd$3(this, _isAuthenticated, __runInitializers$4(_init$4, 8, this, false)), __runInitializers$4(_init$4, 11, this);
|
|
573
|
+
__privateAdd$3(this, _isSetup, __runInitializers$4(_init$4, 12, this, false)), __runInitializers$4(_init$4, 15, this);
|
|
574
|
+
__privateAdd$3(this, _isLoading, __runInitializers$4(_init$4, 16, this, true)), __runInitializers$4(_init$4, 19, this);
|
|
575
|
+
__privateAdd$3(this, _contentList, __runInitializers$4(_init$4, 20, this, [])), __runInitializers$4(_init$4, 23, this);
|
|
576
|
+
__privateAdd$3(this, _statusMessage, __runInitializers$4(_init$4, 24, this, "")), __runInitializers$4(_init$4, 27, this);
|
|
577
|
+
__privateAdd$3(this, _activeSection, __runInitializers$4(_init$4, 28, this, "profile")), __runInitializers$4(_init$4, 31, this);
|
|
578
|
+
__privateAdd$3(this, _staticDetails, __runInitializers$4(_init$4, 32, this, {})), __runInitializers$4(_init$4, 35, this);
|
|
579
|
+
__privateAdd$3(this, _loginError, __runInitializers$4(_init$4, 36, this, "")), __runInitializers$4(_init$4, 39, this);
|
|
580
580
|
}
|
|
581
581
|
get apiUrl() {
|
|
582
582
|
return window.__VITE_API_URL__ || void 0 || "http://localhost:8787";
|
|
583
583
|
}
|
|
584
|
-
|
|
584
|
+
async connectedCallback() {
|
|
585
|
+
super.connectedCallback();
|
|
586
|
+
await this.checkAuthStatus();
|
|
587
|
+
}
|
|
588
|
+
async checkAuthStatus() {
|
|
589
|
+
try {
|
|
590
|
+
const res = await fetch(`${this.apiUrl}/auth/status`, {
|
|
591
|
+
credentials: "include"
|
|
592
|
+
});
|
|
593
|
+
if (res.ok) {
|
|
594
|
+
const status = await res.json();
|
|
595
|
+
this.isSetup = status.configured;
|
|
596
|
+
if (status.configured) {
|
|
597
|
+
await this.tryAutoLogin();
|
|
598
|
+
} else {
|
|
599
|
+
this.isLoading = false;
|
|
600
|
+
}
|
|
601
|
+
} else {
|
|
602
|
+
this.isSetup = false;
|
|
603
|
+
this.isLoading = false;
|
|
604
|
+
}
|
|
605
|
+
} catch (e2) {
|
|
606
|
+
this.isSetup = false;
|
|
607
|
+
this.isLoading = false;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
async tryAutoLogin() {
|
|
611
|
+
try {
|
|
612
|
+
const res = await fetch(`${this.apiUrl}/content`, {
|
|
613
|
+
credentials: "include"
|
|
614
|
+
});
|
|
615
|
+
if (res.ok) {
|
|
616
|
+
this.contentList = await res.json();
|
|
617
|
+
this.isAuthenticated = true;
|
|
618
|
+
}
|
|
619
|
+
} catch (e2) {
|
|
620
|
+
}
|
|
621
|
+
this.isLoading = false;
|
|
622
|
+
}
|
|
623
|
+
async handleLogin(e2) {
|
|
585
624
|
e2.preventDefault();
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
this.
|
|
625
|
+
this.loginError = "";
|
|
626
|
+
const usernameInput = this.shadowRoot?.querySelector("#username");
|
|
627
|
+
const passwordInput = this.shadowRoot?.querySelector("#password");
|
|
628
|
+
if (!usernameInput?.value || !passwordInput?.value) {
|
|
629
|
+
this.loginError = "Username and password required";
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
try {
|
|
633
|
+
const res = await fetch(`${this.apiUrl}/auth/login`, {
|
|
634
|
+
method: "POST",
|
|
635
|
+
credentials: "include",
|
|
636
|
+
headers: { "Content-Type": "application/json" },
|
|
637
|
+
body: JSON.stringify({
|
|
638
|
+
username: usernameInput.value,
|
|
639
|
+
password: passwordInput.value
|
|
640
|
+
})
|
|
641
|
+
});
|
|
642
|
+
if (res.ok) {
|
|
643
|
+
this.isAuthenticated = true;
|
|
644
|
+
await this.fetchContent();
|
|
645
|
+
} else {
|
|
646
|
+
const data = await res.json();
|
|
647
|
+
this.loginError = data.error || "Login failed";
|
|
648
|
+
}
|
|
649
|
+
} catch (e22) {
|
|
650
|
+
this.loginError = "Connection error";
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
async handleSetup(e2) {
|
|
654
|
+
e2.preventDefault();
|
|
655
|
+
this.loginError = "";
|
|
656
|
+
const usernameInput = this.shadowRoot?.querySelector("#username");
|
|
657
|
+
const passwordInput = this.shadowRoot?.querySelector("#password");
|
|
658
|
+
const confirmInput = this.shadowRoot?.querySelector("#confirmPassword");
|
|
659
|
+
if (!usernameInput?.value || !passwordInput?.value) {
|
|
660
|
+
this.loginError = "Username and password required";
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
if (usernameInput.value.length < 3) {
|
|
664
|
+
this.loginError = "Username must be at least 3 characters";
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
if (passwordInput.value.length < 8) {
|
|
668
|
+
this.loginError = "Password must be at least 8 characters";
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
if (passwordInput.value !== confirmInput?.value) {
|
|
672
|
+
this.loginError = "Passwords do not match";
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
try {
|
|
676
|
+
const res = await fetch(`${this.apiUrl}/auth/setup`, {
|
|
677
|
+
method: "POST",
|
|
678
|
+
credentials: "include",
|
|
679
|
+
headers: { "Content-Type": "application/json" },
|
|
680
|
+
body: JSON.stringify({
|
|
681
|
+
username: usernameInput.value,
|
|
682
|
+
password: passwordInput.value
|
|
683
|
+
})
|
|
684
|
+
});
|
|
685
|
+
if (res.ok) {
|
|
686
|
+
this.isAuthenticated = true;
|
|
687
|
+
this.isSetup = true;
|
|
688
|
+
await this.fetchContent();
|
|
689
|
+
} else {
|
|
690
|
+
const data = await res.json();
|
|
691
|
+
this.loginError = data.error || "Setup failed";
|
|
692
|
+
}
|
|
693
|
+
} catch (e22) {
|
|
694
|
+
this.loginError = "Connection error";
|
|
591
695
|
}
|
|
592
696
|
}
|
|
697
|
+
async handleLogout() {
|
|
698
|
+
try {
|
|
699
|
+
await fetch(`${this.apiUrl}/auth/logout`, {
|
|
700
|
+
method: "POST",
|
|
701
|
+
credentials: "include"
|
|
702
|
+
});
|
|
703
|
+
} catch (e2) {
|
|
704
|
+
}
|
|
705
|
+
this.isAuthenticated = false;
|
|
706
|
+
this.contentList = [];
|
|
707
|
+
}
|
|
593
708
|
async fetchContent() {
|
|
594
709
|
try {
|
|
595
710
|
const res = await fetch(`${this.apiUrl}/content`, {
|
|
596
|
-
|
|
597
|
-
"Authorization": `Bearer ${this.apiKey}`
|
|
598
|
-
}
|
|
711
|
+
credentials: "include"
|
|
599
712
|
});
|
|
600
713
|
if (res.ok) {
|
|
601
714
|
this.contentList = await res.json();
|
|
@@ -608,7 +721,9 @@ class AdminPortal extends (_a$4 = LitElement, _apiKey_dec = [state()], _isAuthen
|
|
|
608
721
|
}
|
|
609
722
|
async fetchStaticDetails() {
|
|
610
723
|
try {
|
|
611
|
-
const res = await fetch(`${this.apiUrl}/
|
|
724
|
+
const res = await fetch(`${this.apiUrl}/static`, {
|
|
725
|
+
credentials: "include"
|
|
726
|
+
});
|
|
612
727
|
if (res.ok) {
|
|
613
728
|
this.staticDetails = await res.json();
|
|
614
729
|
}
|
|
@@ -620,9 +735,7 @@ class AdminPortal extends (_a$4 = LitElement, _apiKey_dec = [state()], _isAuthen
|
|
|
620
735
|
this.statusMessage = "Uploading...";
|
|
621
736
|
const res = await fetch(`${this.apiUrl}/content/${key}`, {
|
|
622
737
|
method: "PUT",
|
|
623
|
-
|
|
624
|
-
"Authorization": `Bearer ${this.apiKey}`
|
|
625
|
-
},
|
|
738
|
+
credentials: "include",
|
|
626
739
|
body: file
|
|
627
740
|
});
|
|
628
741
|
if (res.ok) {
|
|
@@ -640,9 +753,7 @@ class AdminPortal extends (_a$4 = LitElement, _apiKey_dec = [state()], _isAuthen
|
|
|
640
753
|
this.statusMessage = "Clearing cache...";
|
|
641
754
|
const res = await fetch(`${this.apiUrl}/cache-clear`, {
|
|
642
755
|
method: "POST",
|
|
643
|
-
|
|
644
|
-
"Authorization": `Bearer ${this.apiKey}`
|
|
645
|
-
}
|
|
756
|
+
credentials: "include"
|
|
646
757
|
});
|
|
647
758
|
if (res.ok) {
|
|
648
759
|
this.statusMessage = "Cache cleared!";
|
|
@@ -658,9 +769,7 @@ class AdminPortal extends (_a$4 = LitElement, _apiKey_dec = [state()], _isAuthen
|
|
|
658
769
|
try {
|
|
659
770
|
const res = await fetch(`${this.apiUrl}/content/${key}`, {
|
|
660
771
|
method: "DELETE",
|
|
661
|
-
|
|
662
|
-
"Authorization": `Bearer ${this.apiKey}`
|
|
663
|
-
}
|
|
772
|
+
credentials: "include"
|
|
664
773
|
});
|
|
665
774
|
if (res.ok) {
|
|
666
775
|
this.fetchContent();
|
|
@@ -677,6 +786,39 @@ class AdminPortal extends (_a$4 = LitElement, _apiKey_dec = [state()], _isAuthen
|
|
|
677
786
|
getSectionFiles(prefix) {
|
|
678
787
|
return this.contentList.filter((c2) => c2.key.startsWith(prefix));
|
|
679
788
|
}
|
|
789
|
+
renderLoginForm() {
|
|
790
|
+
return html`
|
|
791
|
+
<div class="container">
|
|
792
|
+
<div class="login-box">
|
|
793
|
+
<h2>Admin Setup</h2>
|
|
794
|
+
<p>Create your admin credentials</p>
|
|
795
|
+
<form @submit=${this.handleSetup}>
|
|
796
|
+
<input type="text" id="username" placeholder="Username (3+ chars)" />
|
|
797
|
+
<input type="password" id="password" placeholder="Password (8+ chars)" />
|
|
798
|
+
<input type="password" id="confirmPassword" placeholder="Confirm Password" />
|
|
799
|
+
${this.loginError ? html`<div class="error-message">${this.loginError}</div>` : ""}
|
|
800
|
+
<button type="submit" class="btn-primary">Create Account</button>
|
|
801
|
+
</form>
|
|
802
|
+
</div>
|
|
803
|
+
</div>
|
|
804
|
+
`;
|
|
805
|
+
}
|
|
806
|
+
renderLogin() {
|
|
807
|
+
return html`
|
|
808
|
+
<div class="container">
|
|
809
|
+
<div class="login-box">
|
|
810
|
+
<h2>Admin Login</h2>
|
|
811
|
+
<p>Enter your credentials</p>
|
|
812
|
+
<form @submit=${this.handleLogin}>
|
|
813
|
+
<input type="text" id="username" placeholder="Username" autocomplete="username" />
|
|
814
|
+
<input type="password" id="password" placeholder="Password" autocomplete="current-password" />
|
|
815
|
+
${this.loginError ? html`<div class="error-message">${this.loginError}</div>` : ""}
|
|
816
|
+
<button type="submit" class="btn-primary">Login</button>
|
|
817
|
+
</form>
|
|
818
|
+
</div>
|
|
819
|
+
</div>
|
|
820
|
+
`;
|
|
821
|
+
}
|
|
680
822
|
renderHomeSection() {
|
|
681
823
|
const home = this.getContent("home.md");
|
|
682
824
|
return html`
|
|
@@ -875,67 +1017,6 @@ class AdminPortal extends (_a$4 = LitElement, _apiKey_dec = [state()], _isAuthen
|
|
|
875
1017
|
</div>
|
|
876
1018
|
`;
|
|
877
1019
|
}
|
|
878
|
-
render() {
|
|
879
|
-
if (!this.isAuthenticated) {
|
|
880
|
-
return html`
|
|
881
|
-
<div class="container">
|
|
882
|
-
<div class="login-box">
|
|
883
|
-
<h2>Admin Login</h2>
|
|
884
|
-
<p>Enter your API key to manage content</p>
|
|
885
|
-
<form @submit=${this.handleLogin}>
|
|
886
|
-
<input type="password" id="apiKey" placeholder="API Key" />
|
|
887
|
-
<button type="submit" class="btn-primary">Login</button>
|
|
888
|
-
</form>
|
|
889
|
-
</div>
|
|
890
|
-
</div>
|
|
891
|
-
`;
|
|
892
|
-
}
|
|
893
|
-
return html`
|
|
894
|
-
<div class="container">
|
|
895
|
-
<div class="header">
|
|
896
|
-
<h1>Content Manager</h1>
|
|
897
|
-
<button class="btn-secondary" @click=${() => this.handleClearCache()}>Clear Cache</button>
|
|
898
|
-
</div>
|
|
899
|
-
|
|
900
|
-
<div class="nav-tabs">
|
|
901
|
-
<button class="nav-tab ${this.activeSection === "home" ? "active" : ""}"
|
|
902
|
-
@click=${() => this.activeSection = "home"}>Home</button>
|
|
903
|
-
<button class="nav-tab ${this.activeSection === "profile" ? "active" : ""}"
|
|
904
|
-
@click=${() => this.activeSection = "profile"}>Profile</button>
|
|
905
|
-
<button class="nav-tab ${this.activeSection === "aboutme" ? "active" : ""}"
|
|
906
|
-
@click=${() => this.activeSection = "aboutme"}>About Me</button>
|
|
907
|
-
<button class="nav-tab ${this.activeSection === "blogs" ? "active" : ""}"
|
|
908
|
-
@click=${() => this.activeSection = "blogs"}>Blogs</button>
|
|
909
|
-
<button class="nav-tab ${this.activeSection === "stories" ? "active" : ""}"
|
|
910
|
-
@click=${() => this.activeSection = "stories"}>Stories</button>
|
|
911
|
-
<button class="nav-tab ${this.activeSection === "images" ? "active" : ""}"
|
|
912
|
-
@click=${() => this.activeSection = "images"}>Images</button>
|
|
913
|
-
<button class="nav-tab ${this.activeSection === "logo" ? "active" : ""}"
|
|
914
|
-
@click=${() => this.activeSection = "logo"}>Logo</button>
|
|
915
|
-
<button class="nav-tab ${this.activeSection === "static" ? "active" : ""}"
|
|
916
|
-
@click=${() => {
|
|
917
|
-
this.activeSection = "static";
|
|
918
|
-
this.fetchStaticDetails();
|
|
919
|
-
}}>Site Settings</button>
|
|
920
|
-
</div>
|
|
921
|
-
|
|
922
|
-
${this.statusMessage ? html`
|
|
923
|
-
<div class="status-message ${this.statusMessage.includes("successful") || this.statusMessage.includes("cleared") ? "success" : this.statusMessage.includes("failed") || this.statusMessage.includes("Error") ? "error" : ""}">
|
|
924
|
-
${this.statusMessage}
|
|
925
|
-
</div>
|
|
926
|
-
` : ""}
|
|
927
|
-
|
|
928
|
-
${this.activeSection === "home" ? this.renderHomeSection() : ""}
|
|
929
|
-
${this.activeSection === "profile" ? this.renderProfileSection() : ""}
|
|
930
|
-
${this.activeSection === "aboutme" ? this.renderAboutMeSection() : ""}
|
|
931
|
-
${this.activeSection === "blogs" ? this.renderBlogsSection() : ""}
|
|
932
|
-
${this.activeSection === "stories" ? this.renderStoriesSection() : ""}
|
|
933
|
-
${this.activeSection === "images" ? this.renderImagesSection() : ""}
|
|
934
|
-
${this.activeSection === "logo" ? this.renderLogoSection() : ""}
|
|
935
|
-
${this.activeSection === "static" ? this.renderStaticSection() : ""}
|
|
936
|
-
</div>
|
|
937
|
-
`;
|
|
938
|
-
}
|
|
939
1020
|
renderStaticSection() {
|
|
940
1021
|
return html`
|
|
941
1022
|
<div class="section">
|
|
@@ -983,7 +1064,8 @@ class AdminPortal extends (_a$4 = LitElement, _apiKey_dec = [state()], _isAuthen
|
|
|
983
1064
|
const url = `${this.apiUrl}/content/staticdetails.json`;
|
|
984
1065
|
const res = await fetch(url, {
|
|
985
1066
|
method: "PUT",
|
|
986
|
-
|
|
1067
|
+
credentials: "include",
|
|
1068
|
+
headers: { "Content-Type": "application/json" },
|
|
987
1069
|
body: JSON.stringify(data)
|
|
988
1070
|
});
|
|
989
1071
|
if (res.ok) {
|
|
@@ -999,20 +1081,81 @@ class AdminPortal extends (_a$4 = LitElement, _apiKey_dec = [state()], _isAuthen
|
|
|
999
1081
|
</div>
|
|
1000
1082
|
`;
|
|
1001
1083
|
}
|
|
1084
|
+
render() {
|
|
1085
|
+
if (this.isLoading) {
|
|
1086
|
+
return html`<div class="container"><div class="loading">Loading...</div></div>`;
|
|
1087
|
+
}
|
|
1088
|
+
if (!this.isSetup) {
|
|
1089
|
+
return this.renderLoginForm();
|
|
1090
|
+
}
|
|
1091
|
+
if (!this.isAuthenticated) {
|
|
1092
|
+
return this.renderLogin();
|
|
1093
|
+
}
|
|
1094
|
+
return html`
|
|
1095
|
+
<div class="container">
|
|
1096
|
+
<div class="header">
|
|
1097
|
+
<h1>Content Manager</h1>
|
|
1098
|
+
<button class="btn-secondary" @click=${() => this.handleLogout()}>Logout</button>
|
|
1099
|
+
<button class="btn-secondary" @click=${() => this.handleClearCache()}>Clear Cache</button>
|
|
1100
|
+
</div>
|
|
1101
|
+
|
|
1102
|
+
<div class="nav-tabs">
|
|
1103
|
+
<button class="nav-tab ${this.activeSection === "home" ? "active" : ""}"
|
|
1104
|
+
@click=${() => this.activeSection = "home"}>Home</button>
|
|
1105
|
+
<button class="nav-tab ${this.activeSection === "profile" ? "active" : ""}"
|
|
1106
|
+
@click=${() => this.activeSection = "profile"}>Profile</button>
|
|
1107
|
+
<button class="nav-tab ${this.activeSection === "aboutme" ? "active" : ""}"
|
|
1108
|
+
@click=${() => this.activeSection = "aboutme"}>About Me</button>
|
|
1109
|
+
<button class="nav-tab ${this.activeSection === "blogs" ? "active" : ""}"
|
|
1110
|
+
@click=${() => this.activeSection = "blogs"}>Blogs</button>
|
|
1111
|
+
<button class="nav-tab ${this.activeSection === "stories" ? "active" : ""}"
|
|
1112
|
+
@click=${() => this.activeSection = "stories"}>Stories</button>
|
|
1113
|
+
<button class="nav-tab ${this.activeSection === "images" ? "active" : ""}"
|
|
1114
|
+
@click=${() => this.activeSection = "images"}>Images</button>
|
|
1115
|
+
<button class="nav-tab ${this.activeSection === "logo" ? "active" : ""}"
|
|
1116
|
+
@click=${() => this.activeSection = "logo"}>Logo</button>
|
|
1117
|
+
<button class="nav-tab ${this.activeSection === "static" ? "active" : ""}"
|
|
1118
|
+
@click=${() => {
|
|
1119
|
+
this.activeSection = "static";
|
|
1120
|
+
this.fetchStaticDetails();
|
|
1121
|
+
}}>Site Settings</button>
|
|
1122
|
+
</div>
|
|
1123
|
+
|
|
1124
|
+
${this.statusMessage ? html`
|
|
1125
|
+
<div class="status-message ${this.statusMessage.includes("successful") || this.statusMessage.includes("cleared") ? "success" : this.statusMessage.includes("failed") || this.statusMessage.includes("Error") ? "error" : ""}">
|
|
1126
|
+
${this.statusMessage}
|
|
1127
|
+
</div>
|
|
1128
|
+
` : ""}
|
|
1129
|
+
|
|
1130
|
+
${this.activeSection === "home" ? this.renderHomeSection() : ""}
|
|
1131
|
+
${this.activeSection === "profile" ? this.renderProfileSection() : ""}
|
|
1132
|
+
${this.activeSection === "aboutme" ? this.renderAboutMeSection() : ""}
|
|
1133
|
+
${this.activeSection === "blogs" ? this.renderBlogsSection() : ""}
|
|
1134
|
+
${this.activeSection === "stories" ? this.renderStoriesSection() : ""}
|
|
1135
|
+
${this.activeSection === "images" ? this.renderImagesSection() : ""}
|
|
1136
|
+
${this.activeSection === "logo" ? this.renderLogoSection() : ""}
|
|
1137
|
+
${this.activeSection === "static" ? this.renderStaticSection() : ""}
|
|
1138
|
+
</div>
|
|
1139
|
+
`;
|
|
1140
|
+
}
|
|
1002
1141
|
}
|
|
1003
1142
|
_init$4 = __decoratorStart$4(_a$4);
|
|
1004
|
-
_apiKey = /* @__PURE__ */ new WeakMap();
|
|
1005
1143
|
_isAuthenticated = /* @__PURE__ */ new WeakMap();
|
|
1144
|
+
_isSetup = /* @__PURE__ */ new WeakMap();
|
|
1145
|
+
_isLoading = /* @__PURE__ */ new WeakMap();
|
|
1006
1146
|
_contentList = /* @__PURE__ */ new WeakMap();
|
|
1007
1147
|
_statusMessage = /* @__PURE__ */ new WeakMap();
|
|
1008
1148
|
_activeSection = /* @__PURE__ */ new WeakMap();
|
|
1009
1149
|
_staticDetails = /* @__PURE__ */ new WeakMap();
|
|
1010
|
-
|
|
1150
|
+
_loginError = /* @__PURE__ */ new WeakMap();
|
|
1011
1151
|
__decorateElement$4(_init$4, 4, "isAuthenticated", _isAuthenticated_dec, AdminPortal, _isAuthenticated);
|
|
1152
|
+
__decorateElement$4(_init$4, 4, "isSetup", _isSetup_dec, AdminPortal, _isSetup);
|
|
1153
|
+
__decorateElement$4(_init$4, 4, "isLoading", _isLoading_dec, AdminPortal, _isLoading);
|
|
1012
1154
|
__decorateElement$4(_init$4, 4, "contentList", _contentList_dec, AdminPortal, _contentList);
|
|
1013
1155
|
__decorateElement$4(_init$4, 4, "statusMessage", _statusMessage_dec, AdminPortal, _statusMessage);
|
|
1014
1156
|
__decorateElement$4(_init$4, 4, "activeSection", _activeSection_dec, AdminPortal, _activeSection);
|
|
1015
1157
|
__decorateElement$4(_init$4, 4, "staticDetails", _staticDetails_dec, AdminPortal, _staticDetails);
|
|
1158
|
+
__decorateElement$4(_init$4, 4, "loginError", _loginError_dec, AdminPortal, _loginError);
|
|
1016
1159
|
AdminPortal = __decorateElement$4(_init$4, 0, "AdminPortal", _AdminPortal_decorators, AdminPortal);
|
|
1017
1160
|
AdminPortal.styles = adminStyles;
|
|
1018
1161
|
__runInitializers$4(_init$4, 1, AdminPortal);
|