Moved files here
This commit is contained in:
commit
c8965f7aee
7 files changed
+250
No files matched your search
@@ -0,0 +1 @@
|
||||
.idea
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Hello Bulma!</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">
|
||||
Hello World
|
||||
</h1>
|
||||
<p class="subtitle">
|
||||
My first website with <strong>Bulma</strong>!
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import { Router, Context, Request } from "https://deno.land/x/oak/mod.ts";
|
||||
import { Pool } from "https://deno.land/x/postgres@v0.17.0/mod.ts";
|
||||
import { createBundle } from "./bundle.ts";
|
||||
const clientBundle = createBundle(
|
||||
new URL("./client.js", import.meta.url),
|
||||
new URL("../import_map.json", import.meta.url),
|
||||
false,
|
||||
);
|
||||
|
||||
export function buildApp(pool: Pool): Router{
|
||||
const router = new Router();
|
||||
function getHeaders(request: Request): Record<string, string>{
|
||||
const ret: Record<string, string> = {};
|
||||
for (const [k, v] of request.headers.entries()) {
|
||||
ret[k] = v;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
router.post("/api/v1/spy", async (ctx: Context) => {
|
||||
const payload = await ctx.request.body().value;
|
||||
payload.request = {
|
||||
ip: ctx.request.ip,
|
||||
ips: ctx.request.ips,
|
||||
url: ctx.request.url.toString(),
|
||||
date: Date.now(),
|
||||
method: ctx.request.method,
|
||||
headers: getHeaders(ctx.request),
|
||||
};
|
||||
const client = await pool.connect();
|
||||
try{
|
||||
const query ="INSERT INTO blog_statistics(raw_data) VALUES ($1)";
|
||||
await client.queryArray(query, [payload]);
|
||||
ctx.response.body = '{}';
|
||||
}finally {
|
||||
client.release()
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/stats", (ctx:Context) => {
|
||||
ctx.response.body = 'hello world'
|
||||
});
|
||||
|
||||
router.get("/toto.js", async (ctx: Context) => {
|
||||
|
||||
ctx.response.body = await clientBundle;
|
||||
});
|
||||
|
||||
return router;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* This part of the code is based on the way `fresh` is bundling the code.
|
||||
* See https://github.com/denoland/fresh/blob/main/src/server/bundle.ts
|
||||
*/
|
||||
|
||||
// @deno-types="https://deno.land/x/esbuild@v0.14.51/mod.d.ts"
|
||||
import * as esbuildNative from "https://deno.land/x/esbuild@v0.14.51/mod.js";
|
||||
import * as esbuildWasm from "https://deno.land/x/esbuild@v0.14.51/wasm.js";
|
||||
import { denoPlugin } from "https://deno.land/x/esbuild_deno_loader@0.5.2/mod.ts";
|
||||
|
||||
const esbuild: typeof esbuildWasm = Deno.run === undefined
|
||||
? esbuildWasm
|
||||
: esbuildNative;
|
||||
|
||||
let esbuildInitialized = false;
|
||||
async function verifyEsbuildInitialized() {
|
||||
if (esbuildInitialized) {
|
||||
return;
|
||||
}
|
||||
console.log(new Date(), "start initializing esbuild");
|
||||
if (Deno.run === undefined) {
|
||||
const wasmURL = new URL("./esbuild@v0.14.51.wasm", import.meta.url).href;
|
||||
const resp = await fetch(wasmURL);
|
||||
const wasm = new Response(resp.body, {
|
||||
headers: { "Content-Type": "application/wasm" },
|
||||
});
|
||||
const wasmModule = await WebAssembly.compileStreaming(wasm);
|
||||
await esbuild.initialize({
|
||||
wasmModule,
|
||||
worker: false,
|
||||
});
|
||||
} else {
|
||||
await esbuild.initialize({});
|
||||
}
|
||||
esbuildInitialized = true;
|
||||
console.log(new Date(), "esbuild initialized");
|
||||
}
|
||||
|
||||
export async function createBundle(
|
||||
entryPoint: URL,
|
||||
importMapURL: URL,
|
||||
isDev?: boolean,
|
||||
) {
|
||||
await verifyEsbuildInitialized();
|
||||
console.log(new Date(), "Bundling", entryPoint.href);
|
||||
const absWorkingDir = Deno.cwd();
|
||||
const res = await esbuild.build({
|
||||
bundle: true,
|
||||
entryPoints: [entryPoint.href],
|
||||
platform: "neutral",
|
||||
treeShaking: true,
|
||||
minify: !isDev,
|
||||
sourcemap: isDev ? "inline" : false,
|
||||
outfile: "",
|
||||
absWorkingDir,
|
||||
outdir: ".",
|
||||
target: ["chrome99", "firefox99", "safari15"],
|
||||
write: false,
|
||||
format: "esm",
|
||||
plugins: [denoPlugin({ importMapURL })],
|
||||
splitting: false,
|
||||
jsx: "automatic",
|
||||
jsxImportSource: "react",
|
||||
});
|
||||
if (res.errors.length > 0) {
|
||||
throw res.errors;
|
||||
}
|
||||
console.log(new Date(), "Finished bundling", entryPoint.href);
|
||||
return res.outputFiles[0].text;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
(function(window){
|
||||
const SPY_KEY = 'spy-key';
|
||||
|
||||
function randomWord(length) {
|
||||
let result = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for(let i = 0; i < length; i++){
|
||||
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function getSpyKey(){
|
||||
return window.localStorage.getItem(SPY_KEY);
|
||||
}
|
||||
|
||||
function generateSpyKey(){
|
||||
const spyKey = randomWord(80);
|
||||
window.localStorage.setItem(SPY_KEY, spyKey);
|
||||
return spyKey;
|
||||
}
|
||||
|
||||
function getOrCreateSpyKey(){
|
||||
return getSpyKey() || generateSpyKey()
|
||||
}
|
||||
|
||||
async function canvasFingerprint() {
|
||||
|
||||
let canvasElement = document.createElement('canvas');
|
||||
let canvasContext = canvasElement.getContext('2d');
|
||||
canvasContext.fillStyle = 'rgba(0,0,0,0.5)';
|
||||
|
||||
canvasContext.fillText('Hello mon coco ☀️ 🙋🏽', 0, 100)
|
||||
|
||||
canvasContext.fillText('d\ne\tdkd', 50, 50)
|
||||
canvasContext.beginPath()
|
||||
canvasContext.arc(20, 20, 20, 0, 6)
|
||||
canvasContext.fillStyle = 'red'
|
||||
canvasContext.fill()
|
||||
let canvasData = (new TextEncoder).encode(canvasElement.toDataURL())
|
||||
let canvasFingerprint = await crypto.subtle.digest('sha-1', canvasData)
|
||||
|
||||
canvasFingerprint = new Uint8Array(canvasFingerprint)
|
||||
canvasFingerprint = String.fromCharCode(...canvasFingerprint)
|
||||
canvasFingerprint = btoa(canvasFingerprint)
|
||||
|
||||
return canvasFingerprint
|
||||
}
|
||||
|
||||
function getSizes(){
|
||||
return {
|
||||
'window_innerWidth': window.innerWidth,
|
||||
'window_outerWidth': window.outerWidth,
|
||||
'window_innerHeight': window.innerHeight,
|
||||
'window_outerHeight': window.outerHeight,
|
||||
}
|
||||
}
|
||||
|
||||
async function getPayload(){
|
||||
return {
|
||||
windowPerformance: window.performance,
|
||||
sizes: getSizes(),
|
||||
localStorageSpyKey: getOrCreateSpyKey(),
|
||||
canvasFingerPrint: await canvasFingerprint(),
|
||||
};
|
||||
}
|
||||
|
||||
async function publishPayload(payload){
|
||||
const rawResponse = await fetch('/api/v1/spy', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const content = await rawResponse.json();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function main(){
|
||||
await publishPayload(await getPayload());
|
||||
}
|
||||
|
||||
window.setTimeout(main, 1000);
|
||||
})(window)
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
import { Application, Router, Context, Request } from "https://deno.land/x/oak/mod.ts";
|
||||
import { Pool } from "https://deno.land/x/postgres@v0.17.0/mod.ts";
|
||||
import {buildApp} from "./app.ts";
|
||||
import { oakCors } from "https://deno.land/x/cors/mod.ts";
|
||||
import staticFiles from "https://deno.land/x/static_files@1.1.6/mod.ts";
|
||||
|
||||
|
||||
const pool = new Pool(Deno.env.get("POSTGRES_URL"), 2, true);
|
||||
const app = new Application();
|
||||
|
||||
app.use(oakCors({origin: /^.+localhost:8080$/,}));
|
||||
app.use(buildApp(pool).routes());
|
||||
app.use(staticFiles("public", {brotli: true, fetch: true}));
|
||||
|
||||
await app.listen({port:8000});
|
||||
Reference in new issue
Block a user