Skip to content

Commit 0c2e468

Browse files
committed
Cleaned code
1 parent ebc5c1d commit 0c2e468

File tree

15 files changed

+172
-38
lines changed

15 files changed

+172
-38
lines changed

Diff for: .env

+7-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
VITE_PROXY_USE=true
1+
# Set at build time...
2+
VITE_PROXY_USE=true
3+
VITE_ADMIN_MODE=false # Can be override on localstorage.
4+
VITE_RTAPI_DISABLE=false # Can be override on localstorage.
5+
VITE_CRYPTO_SECRET_KEY="secret_key_here"
6+
VITE_CRYPTO_IV_KEY="iv_key_here"
7+
VITE_CRYPTO_SALT_KEY="salt_key_here"

Diff for: .github/workflows/main.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,15 @@ jobs:
1818
- name: 📥 Install dependencies
1919
run: npm install
2020

21+
- name: 🏗️ Lint
22+
run: |
23+
npm run lint
24+
npm run type-check
25+
26+
- name: 🏗️ Test
27+
if: ${{ false }}
28+
run: |
29+
npm run test:unit
30+
2131
- name: 🏗️ Build
2232
run: npm run build

Diff for: package-lock.json

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
"dependencies": {
1919
"@primevue/forms": "^4.2.5",
2020
"@primevue/themes": "^4.2.5",
21+
"@types/crypto-js": "^4.2.2",
2122
"@types/http-proxy": "^1.17.15",
2223
"axios-vue": "^0.1.3",
2324
"chart.js": "^4.4.7",
2425
"chartjs-adapter-date-fns": "^3.0.0",
26+
"crypto-js": "^4.2.0",
2527
"date-fns": "^4.1.0",
2628
"http-proxy": "^1.18.1",
2729
"mitt-vue": "^2.0.3",

Diff for: src/App.vue

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
<script setup lang="ts"></script>
1+
<script setup lang="ts">
2+
// Init Application.
3+
import LocalStorage from '@/stores/localStorage';
4+
new LocalStorage().checkSchemaVersion();
5+
6+
</script>
27

38
<template>
49
<router-view />

Diff for: src/assets/main.css

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ main {
2727
flex-wrap: wrap;
2828
}
2929

30+
.p-card {
31+
margin-bottom: 1.5em;
32+
}
33+
3034
/* a,
3135
.green {
3236
text-decoration: none;

Diff for: src/components/base/api.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import axios, { type AxiosInstance } from 'axios';
22

3+
/**
4+
* API wrapper to call CDN (Fastly).
5+
*/
36
export default abstract class APIService {
47
protected wsClient: AxiosInstance;
58
protected service_id: string;
@@ -9,11 +12,10 @@ export default abstract class APIService {
912
constructor(service_id: string, token: string) {
1013
this.service_id = service_id;
1114

12-
// Common (fetch)
13-
if (import.meta.env.DEV) {
14-
this.baseUrl = 'https://api.fastly.com/'; // Direct Access
15+
if (import.meta.env.VITE_PROXY_USE == 'true') {
16+
this.baseUrl = 'api/'; // Proxy Access
1517
} else {
16-
this.baseUrl = 'api/'; // Proxy Access
18+
this.baseUrl = 'https://api.fastly.com/'; // Direct Access
1719
}
1820

1921
this.headers = {

Diff for: src/components/base/type.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/**
2+
* Entity base on ID.
3+
*/
14
export default interface Identifiable {
25
id: string;
36
}

Diff for: src/components/project/StatCard.vue

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { useToast } from 'primevue/usetoast';
44
import Chart from 'primevue/chart';
55
import ProjectAPIService from './project.service';
66
import 'chartjs-adapter-date-fns';
7-
import ApiCache from '@/stores/localStorage';
7+
import LocalStore from '@/stores/localStorage';
88
99
// Init
10-
const service_token = (new ApiCache()).getFastlyToken() || '';
10+
const localStore = new LocalStore()
11+
const service_token = localStore.getFastlyToken() || '';
1112
const sampleCount = 20;
1213
const toast = useToast();
1314
const props = defineProps({
@@ -61,13 +62,13 @@ const chartOptions = ref({
6162
});
6263
6364
onMounted(() => {
64-
// if (import.meta.env.DEV) {
65+
if (localStore.isRtApiEnable()) {
6566
timer.value = setInterval(() => {
6667
if (!lock.value) {
6768
getNextStat();
6869
}
6970
}, 1000);
70-
// }
71+
}
7172
});
7273
7374
// Clean up

Diff for: src/components/project/project.service.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ export default class ProjectAPIService extends APIService {
1212
constructor(service_id: string, token: string) {
1313
super(service_id, token);
1414

15-
if (import.meta.env.DEV) {
16-
this.baseUrlRt = 'https://rt.fastly.com/'; // Direct Access
15+
if (import.meta.env.VITE_PROXY_USE == 'true') {
16+
this.baseUrlRt = 'rt/'; // Proxy Access
1717
} else {
18-
this.baseUrlRt = 'rt/'; // Proxy Access
18+
this.baseUrlRt = 'https://rt.fastly.com/'; // Direct Access
1919
}
2020

2121
this.wsClientRt = axios.create({

Diff for: src/proxy.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const PORT = process.env.PORT || 8888;
55
const proxy = httpproxy.createProxyServer({});
66

77
const server = http.createServer(function (req, res) {
8-
if (req.url.startsWith("\/api")) {
8+
if (req.url.startsWith("/api")) {
99
req.url = req.url.replace(/^\/api/, '');
1010
proxy.web(req, res, {
1111
target: 'https://api.fastly.com/',
@@ -14,7 +14,7 @@ const server = http.createServer(function (req, res) {
1414
});
1515
} else
1616

17-
if (req.url.startsWith("\/rt")) {
17+
if (req.url.startsWith("/rt")) {
1818
req.url = req.url.replace(/^\/rt/, "");
1919
proxy.web(req, res, {
2020
target: 'https://rt.fastly.com/',

Diff for: src/router/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import AppLayout from '@/layout/AppLayout.vue';
22
import { createRouter, createWebHistory } from 'vue-router';
33

4+
/**
5+
* Global router of App.
6+
*/
47
const router = createRouter({
58
history: createWebHistory(import.meta.env.BASE_URL),
69
routes: [

Diff for: src/stores/localStorage.ts

+82-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,42 @@
11
import type UserEntity from '@/components/project/project.interface';
2+
import CryptoJS from "crypto-js";
23

4+
// Clean schema of local storage. (change this value if you updated the schema)
5+
const SCHEMA_VERSION = 1;
36

4-
const KEY_USERS = "fastlycdn-cache-users";
5-
const KEY_FASTLY_ID = "fastlycdn-api-id";
6-
const KEY_FASTLY_TK = "fastlycdn-api-tk";
7-
export default class UserCache {
7+
// Keys of local storage.
8+
const KEY_USERS = "fastcdn-fastly-cache-users";
9+
const KEY_FASTLY_ID = "fastcdn-fastly-api-id";
10+
const KEY_FASTLY_TK = "fastcdn-fastly-api-tk";
11+
const KEY_ADMIN_MODE = "fastcdn-admin-mode";
12+
const KEY_RTAPI_ENABLE = "fastcdn-rtapi-enable";
13+
const KEY_SCHEMA_VERSION = "fastcdn-schema-version";
814

15+
// Value of encrypt/Decrypt engine.
16+
const SECRET = import.meta.env.VITE_CRYPTO_SECRET_KEY;
17+
const IV = import.meta.env.VITE_CRYPTO_IV_KEY;
18+
const SALT = import.meta.env.VITE_CRYPTO_SALT_KEY;
19+
20+
/**
21+
* Wrapper of localstorage for FastSun.
22+
*/
23+
export default class LocalStore {
24+
25+
/**
26+
* Check version of schema of local storage.
27+
* If not the same, clean all data !
28+
*/
29+
checkSchemaVersion() {
30+
const version = Number(localStorage.getItem(KEY_SCHEMA_VERSION)) || 0;
31+
if (SCHEMA_VERSION !== version) {
32+
localStorage.clear();
33+
localStorage.setItem(KEY_SCHEMA_VERSION, String(SCHEMA_VERSION));
34+
}
35+
}
36+
37+
/**
38+
* Set Cache user from Fastly.
39+
*/
940
setUser(value: UserEntity): void {
1041
const users = JSON.parse(localStorage.getItem(KEY_USERS) || '[]') as Array<UserEntity>;
1142

@@ -16,31 +47,74 @@ export default class UserCache {
1647
}
1748
}
1849

50+
/**
51+
* Get Cache user from Fastly.
52+
* @returns User.
53+
*/
1954
getUser(id: string): UserEntity | undefined {
2055
const users = JSON.parse(localStorage.getItem(KEY_USERS) || '[]') as Array<UserEntity>;
2156
const user = users.find((item) => { return item.id == id});
57+
2258
return user;
2359
}
2460

61+
/**
62+
* Set Fastly service ID.
63+
*/
2564
setFastlyId(fastly_id: string) {
2665
if (fastly_id) {
2766
localStorage.setItem(KEY_FASTLY_ID, fastly_id);
2867
}
2968
}
3069

70+
/**
71+
* Set Fastly service Token (and encrypt them).
72+
*/
3173
setFastlyToken(fastly_token: string) {
3274
if (fastly_token) {
33-
//TODO Encrypt value !!
34-
localStorage.setItem(KEY_FASTLY_TK, fastly_token);
75+
const key = CryptoJS.PBKDF2(SECRET, SALT, { keySize: 256/32, iterations: 100 });
76+
const iv = CryptoJS.enc.Utf8.parse(IV);
77+
const encrypted = CryptoJS.AES.encrypt(fastly_token, key, { iv: iv, mode: CryptoJS.mode.CBC });
78+
const result = encrypted.ciphertext.toString(CryptoJS.enc.Hex);
79+
localStorage.setItem(KEY_FASTLY_TK, result);
3580
}
3681
}
3782

83+
/**
84+
* Get Fastly service ID.
85+
* @returns Fastly service ID.
86+
*/
3887
getFastlyId(): string {
3988
return localStorage.getItem(KEY_FASTLY_ID) || '';
4089
}
4190

91+
/**
92+
* Get Fastly service Token (and decrypt them).
93+
* @returns Fastly service Token.
94+
*/
4295
getFastlyToken(): string {
43-
//TODO Decrypt value !!
44-
return localStorage.getItem(KEY_FASTLY_TK) || '';
96+
const encryptValue = localStorage.getItem(KEY_FASTLY_TK) || '';
97+
const key = CryptoJS.PBKDF2(SECRET, SALT, { keySize: 256/32, iterations: 100 });
98+
const iv = CryptoJS.enc.Utf8.parse(IV);
99+
const cipher = CryptoJS.enc.Hex.parse(encryptValue);
100+
const decrypted = CryptoJS.AES.decrypt({ ciphertext: cipher } as CryptoJS.lib.CipherParams, key, { iv: iv, mode: CryptoJS.mode.CBC });
101+
const result = decrypted.toString(CryptoJS.enc.Utf8);
102+
return result;
103+
}
104+
105+
/**
106+
* Check override of Admin mode.
107+
* @returns True if enabled.
108+
*/
109+
isAdminMode(): boolean {
110+
return localStorage.getItem(KEY_ADMIN_MODE) == 'true' || import.meta.env.VITE_ADMIN_MODE == 'true';
111+
}
112+
113+
/**
114+
* Check override of RT-API is enabled.
115+
* @returns True if enabled.
116+
*/
117+
isRtApiEnable(): boolean {
118+
return localStorage.getItem(KEY_RTAPI_ENABLE) == 'true' || import.meta.env.VITE_RTAPI_DISABLE == 'false';
45119
}
46120
}

Diff for: src/utils/eventBus.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import mitt from 'mitt';
22

3+
/**
4+
* List of global event type.
5+
*/
36
export const enum EventType {
47
LOG_REFRESH = 'log.refresh',
58
}
69

10+
/**
11+
* Global event engine.
12+
*/
713
export const eventBus = mitt();

0 commit comments

Comments
 (0)