forked from umami-software/umami
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f7f0c05
Showing
27 changed files
with
13,028 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"env": { | ||
"browser": true, | ||
"es2020": true | ||
}, | ||
"extends": ["eslint:recommended", "plugin:react/recommended", "prettier", "prettier/react"], | ||
"parserOptions": { | ||
"ecmaFeatures": { | ||
"jsx": true | ||
}, | ||
"ecmaVersion": 11, | ||
"sourceType": "module" | ||
}, | ||
"plugins": ["react"], | ||
"rules": { | ||
"react/react-in-jsx-scope": "off" | ||
}, | ||
"globals": { | ||
"React": "writable" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.idea | ||
*.iml | ||
.env | ||
.env*.local | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"arrowParens": "avoid", | ||
"endOfLine": "lf", | ||
"printWidth": 100, | ||
"singleQuote": true, | ||
"trailingComma": "all" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"extends": [ | ||
"stylelint-config-recommended", | ||
"stylelint-config-css-modules", | ||
"stylelint-config-prettier" | ||
], | ||
"rules": { | ||
"no-descending-specificity": null, | ||
"selector-pseudo-class-no-unknown": [ | ||
true, | ||
{ | ||
"ignorePseudoClasses": ["global", "horizontal", "vertical"] | ||
} | ||
] | ||
}, | ||
"ignoreFiles": ["**/*.js"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
umami - deliciously simple web stats |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import React from 'react'; | ||
|
||
export default function Footer() { | ||
return <footer className="container">Footer</footer>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
export default function Header() { | ||
return <header className="container"> | ||
<h1>umami</h1> | ||
</header>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import React from 'react'; | ||
import Head from 'next/head'; | ||
import Header from 'components/header'; | ||
import Footer from 'components/footer'; | ||
|
||
export default function Layout({ title, children }) { | ||
return ( | ||
<> | ||
<Head> | ||
<title>umami{title && ` - ${title}`}</title> | ||
<link rel="icon" href="/favicon.ico" /> | ||
<link | ||
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap" | ||
rel="stylesheet" | ||
/> | ||
<script async defer data-website-id="865234ad-6a92-11e7-8846-b05adad3f099" src="/umami.js" /> | ||
</Head> | ||
<Header /> | ||
<main className="container">{children}</main> | ||
<Footer /> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"compilerOptions": { | ||
"baseUrl": "." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { PrismaClient } from '@prisma/client'; | ||
|
||
const prisma = new PrismaClient(); | ||
|
||
export async function runQuery(query) { | ||
return query | ||
.catch(e => { | ||
throw e; | ||
}) | ||
.finally(async () => { | ||
await prisma.disconnect(); | ||
}); | ||
} | ||
|
||
export async function getWebsite(website_id) { | ||
return runQuery( | ||
prisma.website.findOne({ | ||
where: { | ||
website_id, | ||
}, | ||
}), | ||
); | ||
} | ||
|
||
export async function createSession(website_id, session_id, data) { | ||
await runQuery( | ||
prisma.session.create({ | ||
data: { | ||
session_id, | ||
website: { | ||
connect: { | ||
website_id, | ||
}, | ||
}, | ||
...data, | ||
}, | ||
}), | ||
); | ||
} | ||
|
||
export async function getSession(session_id) { | ||
return runQuery( | ||
prisma.session.findOne({ | ||
where: { | ||
session_id, | ||
}, | ||
}), | ||
); | ||
} | ||
|
||
export async function savePageView(session_id, url, referrer) { | ||
return runQuery( | ||
prisma.pageview.create({ | ||
data: { | ||
session: { | ||
connect: { | ||
session_id, | ||
}, | ||
}, | ||
url, | ||
referrer, | ||
}, | ||
}), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import crypto from 'crypto'; | ||
import { v5 as uuid } from 'uuid'; | ||
import requestIp from 'request-ip'; | ||
import { browserName, detectOS } from 'detect-browser'; | ||
|
||
export function md5(s) { | ||
return crypto.createHash('md5').update(s).digest('hex'); | ||
} | ||
|
||
export function hash(s) { | ||
return uuid(s, md5(process.env.HASH_SALT)); | ||
} | ||
|
||
export function getIpAddress(req) { | ||
if (req.headers['cf-connecting-ip']) { | ||
return req.headers['cf-connecting-ip']; | ||
} | ||
return requestIp.getClientIp(req); | ||
} | ||
|
||
export function getDevice(req) { | ||
const userAgent = req.headers['user-agent']; | ||
const browser = browserName(userAgent); | ||
const os = detectOS(userAgent); | ||
|
||
return { userAgent, browser, os }; | ||
} | ||
|
||
export function getCountry(req) { | ||
return req.headers['cf-ipcountry']; | ||
} | ||
|
||
export function parseSessionRequest(req) { | ||
const ip = getIpAddress(req); | ||
const { website_id, screen, language } = JSON.parse(req.body); | ||
const { userAgent, browser, os } = getDevice(req); | ||
const country = getCountry(req); | ||
const session_id = hash(`${website_id}${ip}${userAgent}${os}`); | ||
|
||
return { | ||
website_id, | ||
session_id, | ||
browser, | ||
os, | ||
screen, | ||
language, | ||
country, | ||
}; | ||
} | ||
|
||
export function parseCollectRequest(req) { | ||
const { type, payload } = JSON.parse(req.body); | ||
|
||
if (payload.session) { | ||
const { | ||
url, | ||
referrer, | ||
session: { website_id, session_id, time, hash: validationHash }, | ||
} = payload; | ||
|
||
if (hash(`${website_id}${session_id}${time}`) === validationHash) { | ||
return { | ||
type, | ||
session_id, | ||
url, | ||
referrer, | ||
}; | ||
} | ||
} | ||
|
||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
require('dotenv').config(); | ||
|
||
module.exports = { | ||
webpack(config) { | ||
config.module.rules.push({ | ||
test: /\.svg$/, | ||
issuer: { | ||
test: /\.js$/, | ||
}, | ||
use: ['@svgr/webpack'], | ||
}); | ||
|
||
return config; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
{ | ||
"name": "umami", | ||
"version": "0.1.0", | ||
"description": "Deliciously simple website analytics", | ||
"main": "index.js", | ||
"author": "Mike Cao", | ||
"license": "MIT", | ||
"scripts": { | ||
"dev": "next dev -p 8000", | ||
"build": "next build", | ||
"start": "next start", | ||
"build-script": "rollup -c" | ||
}, | ||
"lint-staged": { | ||
"**/*.js": [ | ||
"prettier --write" | ||
], | ||
"**/*.css": [ | ||
"stylelint --fix", | ||
"prettier --write" | ||
] | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
}, | ||
"dependencies": { | ||
"@prisma/client": "2.2.2", | ||
"classnames": "^2.2.6", | ||
"date-fns": "^2.14.0", | ||
"detect-browser": "^5.1.1", | ||
"dotenv": "^8.2.0", | ||
"next": "9.3.5", | ||
"node-fetch": "^2.6.0", | ||
"react": "16.13.1", | ||
"react-dom": "16.13.1", | ||
"request-ip": "^2.1.3", | ||
"uuid": "^8.2.0", | ||
"whatwg-fetch": "^3.2.0" | ||
}, | ||
"devDependencies": { | ||
"@prisma/cli": "2.2.2", | ||
"@rollup/plugin-node-resolve": "^8.4.0", | ||
"@svgr/webpack": "^5.4.0", | ||
"eslint": "^7.2.0", | ||
"eslint-config-prettier": "^6.11.0", | ||
"eslint-plugin-prettier": "^3.1.3", | ||
"eslint-plugin-react": "^7.20.0", | ||
"eslint-plugin-react-hooks": "^4.0.4", | ||
"husky": "^4.2.5", | ||
"less": "^3.11.3", | ||
"lint-staged": "^10.2.9", | ||
"postcss-flexbugs-fixes": "^4.2.1", | ||
"postcss-import": "^12.0.1", | ||
"postcss-preset-env": "^6.7.0", | ||
"prettier": "^2.0.5", | ||
"prettier-eslint": "^10.1.1", | ||
"rollup": "^2.21.0", | ||
"rollup-plugin-replace": "^2.2.0", | ||
"rollup-plugin-terser": "^6.1.0", | ||
"stylelint": "^13.6.0", | ||
"stylelint-config-css-modules": "^2.2.0", | ||
"stylelint-config-prettier": "^8.0.1", | ||
"stylelint-config-recommended": "^3.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React from 'react'; | ||
import Layout from 'components/layout'; | ||
|
||
export default function Custom404() { | ||
return ( | ||
<Layout title="404 - Page Not Found"> | ||
<h1>oops</h1> | ||
</Layout> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
import 'styles/index.css'; | ||
import 'styles/bootstrap-grid.css'; | ||
|
||
export default function App({ Component, pageProps }) { | ||
return <Component {...pageProps} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { parseCollectRequest } from 'lib/utils'; | ||
import { savePageView } from '../../lib/db'; | ||
|
||
export default async (req, res) => { | ||
const values = parseCollectRequest(req); | ||
|
||
if (values) { | ||
const { type, session_id, url, referrer } = values; | ||
|
||
if (type === 'pageview') { | ||
await savePageView(session_id, url, referrer); | ||
} | ||
} | ||
|
||
res.status(200).json({ status: 'ok' }); | ||
}; |
Oops, something went wrong.