Skip to content
Snippets Groups Projects
Commit cde5f2ab authored by Samantha Fisher's avatar Samantha Fisher
Browse files

Merge branch 'site-base' into 'main'

last minute fixes, readme update for site branch (not root readme yet)

See merge request !8
parents 2d81341c d1af545d
No related branches found
No related tags found
1 merge request!8last minute fixes, readme update for site branch (not root readme yet)
Showing
with 491 additions and 5065 deletions
pi/tmp/*
*__pycache__*
*.pyc
/site
/node_modules
/build
tsconfig.tsbuildinfo
......
An adapter module to interface the site with a dummy SQLite database. Another module will be written when hosting solutions are finished that will interface with the PostGreSQL database.
# How to Use
If the packages aren't installed on your system, first run `npm install`
To run unit tests, ensure you are in the database directory and run `npx jest`
\ No newline at end of file
module.exports = {
transform: {'^.+\\.ts?$': 'ts-jest'},
testEnvironment: 'node',
testRegex: '/src/tests/.*\\.(test|spec)?\\.(ts|tsx)$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
}
\ No newline at end of file
This diff is collapsed.
{
"scripts": {},
"dependencies": {
"@types/jest": "^29.5.14",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7"
},
"devDependencies": {
"@types/node": "^22.13.9",
"jest": "^29.7.0",
"ts-jest": "^29.2.6",
"typescript": "^5.8.2"
},
"name": "database",
"description": "An adapter module to interface the site with a dummy SQLite database.",
"version": "1.0.0",
"main": "database.js",
"author": "Samantha Fisher",
"license": "UNLICENSED"
}
import { verbose, Database } from "sqlite3";
import { open, Database as sqliteDatabase } from "sqlite";
import { UserDetails, DatabaseRequestStatus } from "./types/types";
import { stat } from "fs/promises";
// god the amount i could do if js had 'using' like in python
export const SUCCESS: DatabaseRequestStatus = { code: 0 };
// debugging, remove for release
verbose();
async function fileExists(fname: string) : Promise<Boolean> {
try {
await stat(fname);
return true;
} catch (error) {
return false;
}
}
export async function createUser(fname: string, userDetails: UserDetails): Promise<DatabaseRequestStatus> {
// check if the database exists
if (!await fileExists(fname)) {
return { error: "Database does not exist", code: 1 };
}
// define database variable before opening
let db: sqliteDatabase;
// try to open database, if database fails to open return error status
try {
db = await open({
filename: fname,
driver: Database
});
} catch (error) {
return { error: "Could not open database", code: 5 };
}
// try to write to database, if writing fails return error status and close database
try {
await db.run(
`INSERT INTO users (name, email, pass) VALUES ($name, $email, $pass)`,
{
$name: userDetails.name,
$email: userDetails.email,
$pass: userDetails.pass
}
);
} catch (error) {
// if duplicate emails, a 'sqlite_constraint' error will be thrown
// catch it and return a status code 2, closing the database
if (error.code == "SQLITE_CONSTRAINT") {
await db.close();
return { error: "A user with this email already exists", code: 2 };
}
// if unknown error, close database and return code 3
await db.close();
return { error: "Could not write to database", code: 3 };
}
// return success status and close database
await db.close();
return SUCCESS;
}
export async function createDatabase(fname: string) : Promise<DatabaseRequestStatus>{
// do not create database if it exists
if (await fileExists(fname)) {
return { error: "Database already exists", code: 3 };
}
// instantiate db variable before opening database
let db: sqliteDatabase;
// try opening database, if failed, return error status 5
try {
db = await open({
filename: fname,
driver: Database
});
} catch (error) {
return { error: "Could not open database", code: 5 };
}
// try to create users table
try {
await db.run(`
CREATE TABLE users
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
pass TEXT NOT NULL
)
`);
} catch (error) {
/* if table could not be created, close database and return error code 4
* this will be thrown due to a duplicate table if the database already exists
* however this is checked so shouldn't happen
*/
await db.close();
return { error: "Could not create database", code: 4 };
}
// close database and return success status
await db.close();
return SUCCESS;
}
export async function getUserHash(fname: string, email: String) : Promise<{status: DatabaseRequestStatus, hash?: string}>{
// check if the database exists
if (!await fileExists(fname)) {
// if database does not exist, return appropriate error status
return {status:{ error: "Database does not exist", code: 1 }};
}
// declare db variable before opening database
let db: sqliteDatabase;
// try opening database, return error on failure
try {
db = await open({
filename: fname,
driver: Database
});
} catch (error) {
return {status:{ error: "Could not open database", code: 5 }};
}
// try to get the hash from the database
let result;
try {
result = await db.get(`
SELECT pass FROM users WHERE email = $email`,
{
$email: email,
});
} catch (error) {
// if the email does not exist, return an error and close the database
await db.close();
return {status:{ error: "Could not read from database", code: 7 }};
}
// if the email is not recognised by the database, i.e. it returns no rows, return an error and close the database
if (!result) {
await db.close();
return {status:{ error: "User does not exist", code : 6 }};
}
// close database and return success alongside user hash
await db.close();
return {status: SUCCESS, hash: result.pass};
}
\ No newline at end of file
This diff is collapsed.
export type UserDetails = {
name: string,
email: string,
pass: string
}
export type DatabaseRequestStatus = {
error?: string;
code: 0 // success
| 1 // Database does not exist
| 2 // A user with this email already exists
| 3 // Database already exists
| 4 // Could not create database
| 5 // Could not open database
| 6 // User does not exist
| 7 // Could not read from database
}
{
"compilerOptions": {
"target": "es6",
"module": "CommonJS",
"sourceMap": true,
"rootDir": "src",
"outDir": "build",
},
}
\ No newline at end of file
.now/*
*.css
.changeset
dist
esm/*
public/*
tests/*
scripts/*
*.config.js
.DS_Store
node_modules
coverage
.next
build
!.commitlintrc.cjs
!.lintstagedrc.cjs
!jest.config.js
!plopfile.js
!react-shim.js
!tsup.config.ts
\ No newline at end of file
{
"$schema": "https://json.schemastore.org/eslintrc.json",
"env": {
"browser": false,
"es2021": true,
"node": true
},
"extends": [
"plugin:react/recommended",
"plugin:prettier/recommended",
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended",
"plugin:@next/next/recommended"
],
"plugins": ["react", "unused-imports", "import", "@typescript-eslint", "jsx-a11y", "prettier"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"no-console": "warn",
"react/prop-types": "off",
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off",
"react-hooks/exhaustive-deps": "off",
"jsx-a11y/click-events-have-key-events": "warn",
"jsx-a11y/interactive-supports-focus": "warn",
"prettier/prettier": "warn",
"no-unused-vars": "off",
"linebreak-style": "off",
"endOfLine": "off",
"unused-imports/no-unused-vars": "off",
"unused-imports/no-unused-imports": "warn",
"@typescript-eslint/no-unused-vars": [
"warn",
{
"args": "after-used",
"ignoreRestSiblings": false,
"argsIgnorePattern": "^_.*?$"
}
],
"import/order": [
"warn",
{
"groups": [
"type",
"builtin",
"object",
"external",
"internal",
"parent",
"sibling",
"index"
],
"pathGroups": [
{
"pattern": "~/**",
"group": "external",
"position": "after"
}
],
"newlines-between": "always"
}
],
"react/self-closing-comp": "warn",
"react/jsx-sort-props": [
"warn",
{
"callbacksLast": true,
"shorthandFirst": true,
"noSortAlphabetically": false,
"reservedFirst": true
}
],
"padding-line-between-statements": [
"warn",
{"blankLine": "always", "prev": "*", "next": "return"},
{"blankLine": "always", "prev": ["const", "let", "var"], "next": "*"},
{
"blankLine": "any",
"prev": ["const", "let", "var"],
"next": ["const", "let", "var"]
}
]
}
}
This diff is collapsed.
package-lock=true
\ No newline at end of file
{
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
]
}
\ No newline at end of file
{
"typescript.tsdk": "node_modules/typescript/lib"
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment