api key
parent
6fc5d90e6d
commit
00e89f44e8
|
|
@ -1,14 +1,18 @@
|
||||||
.nyc_output/
|
.nyc_output/
|
||||||
bin/daemon/
|
bin/daemon/
|
||||||
coverage/
|
coverage/
|
||||||
|
|
||||||
cypress/downloads/
|
cypress/downloads/
|
||||||
cypress/screenshots/
|
cypress/screenshots/
|
||||||
cypress/videos/
|
cypress/videos/
|
||||||
|
|
||||||
data/sessions/
|
data/sessions/
|
||||||
|
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
data/*.db
|
data/*.db
|
||||||
data/*.db-journal
|
data/*.db-journal
|
||||||
|
data/apiKeys.json
|
||||||
|
|
||||||
data/config.d.ts
|
data/config.d.ts
|
||||||
data/config.js
|
data/config.js
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import * as recordTypes from "../types/recordTypes";
|
||||||
|
export declare const regenerateApiKey: (userName: string) => Promise<void>;
|
||||||
|
export declare const getApiKey: (userName: string) => Promise<string>;
|
||||||
|
export declare const getApiKeyFromSession: (session: recordTypes.PartialSession) => Promise<string>;
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import fs from "node:fs/promises";
|
||||||
|
import crypto from "node:crypto";
|
||||||
|
import Debug from "debug";
|
||||||
|
const debug = Debug("lot-occupancy-system:functions.api");
|
||||||
|
const apiKeyPath = "data/apiKeys.json";
|
||||||
|
let apiKeys;
|
||||||
|
const loadApiKeys = async () => {
|
||||||
|
try {
|
||||||
|
const fileData = await fs.readFile(apiKeyPath, "utf8");
|
||||||
|
apiKeys = JSON.parse(fileData);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
debug(error);
|
||||||
|
apiKeys = {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const saveApiKeys = async () => {
|
||||||
|
try {
|
||||||
|
await fs.writeFile(apiKeyPath, JSON.stringify(apiKeys), "utf8");
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
debug(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const generateApiKey = (apiKeyPrefix) => {
|
||||||
|
return apiKeyPrefix + "-" + crypto.randomUUID() + "-" + Date.now();
|
||||||
|
};
|
||||||
|
export const regenerateApiKey = async (userName) => {
|
||||||
|
apiKeys[userName] = generateApiKey(userName);
|
||||||
|
await saveApiKeys();
|
||||||
|
};
|
||||||
|
export const getApiKey = async (userName) => {
|
||||||
|
if (!apiKeys) {
|
||||||
|
await loadApiKeys();
|
||||||
|
}
|
||||||
|
if (!apiKeys[userName]) {
|
||||||
|
await regenerateApiKey(userName);
|
||||||
|
}
|
||||||
|
return apiKeys[userName];
|
||||||
|
};
|
||||||
|
export const getApiKeyFromSession = async (session) => {
|
||||||
|
return await getApiKey(session.user.userName);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
import fs from "node:fs/promises";
|
||||||
|
import crypto from "node:crypto";
|
||||||
|
|
||||||
|
import Debug from "debug";
|
||||||
|
|
||||||
|
import * as recordTypes from "../types/recordTypes";
|
||||||
|
|
||||||
|
const debug = Debug("lot-occupancy-system:functions.api");
|
||||||
|
|
||||||
|
const apiKeyPath = "data/apiKeys.json";
|
||||||
|
let apiKeys: { [userName: string]: string };
|
||||||
|
|
||||||
|
const loadApiKeys = async () => {
|
||||||
|
try {
|
||||||
|
const fileData = await fs.readFile(apiKeyPath, "utf8");
|
||||||
|
apiKeys = JSON.parse(fileData);
|
||||||
|
} catch (error) {
|
||||||
|
debug(error);
|
||||||
|
apiKeys = {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveApiKeys = async () => {
|
||||||
|
try {
|
||||||
|
await fs.writeFile(apiKeyPath, JSON.stringify(apiKeys), "utf8");
|
||||||
|
} catch (error) {
|
||||||
|
debug(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const generateApiKey = (apiKeyPrefix: string) => {
|
||||||
|
return apiKeyPrefix + "-" + crypto.randomUUID() + "-" + Date.now();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const regenerateApiKey = async (userName: string) => {
|
||||||
|
apiKeys[userName] = generateApiKey(userName);
|
||||||
|
await saveApiKeys();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getApiKey = async (userName: string) => {
|
||||||
|
if (!apiKeys) {
|
||||||
|
await loadApiKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!apiKeys[userName]) {
|
||||||
|
await regenerateApiKey(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apiKeys[userName];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getApiKeyFromSession = async (
|
||||||
|
session: recordTypes.PartialSession
|
||||||
|
) => {
|
||||||
|
return await getApiKey(session.user.userName);
|
||||||
|
};
|
||||||
|
|
@ -13,7 +13,8 @@ const session = {
|
||||||
userName: "init.cemetery",
|
userName: "init.cemetery",
|
||||||
userProperties: {
|
userProperties: {
|
||||||
canUpdate: true,
|
canUpdate: true,
|
||||||
isAdmin: true
|
isAdmin: true,
|
||||||
|
apiKey: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ const session: PartialSession = {
|
||||||
userName: "init.cemetery",
|
userName: "init.cemetery",
|
||||||
userProperties: {
|
userProperties: {
|
||||||
canUpdate: true,
|
canUpdate: true,
|
||||||
isAdmin: true
|
isAdmin: true,
|
||||||
|
apiKey: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { Router } from "express";
|
||||||
import * as configFunctions from "../helpers/functions.config.js";
|
import * as configFunctions from "../helpers/functions.config.js";
|
||||||
import * as authenticationFunctions from "../helpers/functions.authentication.js";
|
import * as authenticationFunctions from "../helpers/functions.authentication.js";
|
||||||
import { useTestDatabases } from "../data/databasePaths.js";
|
import { useTestDatabases } from "../data/databasePaths.js";
|
||||||
|
import { getApiKey } from "../helpers/functions.api.js";
|
||||||
export const router = Router();
|
export const router = Router();
|
||||||
const safeRedirects = new Set([
|
const safeRedirects = new Set([
|
||||||
"/admin/fees",
|
"/admin/fees",
|
||||||
|
|
@ -75,11 +76,13 @@ router
|
||||||
.some((currentUserName) => {
|
.some((currentUserName) => {
|
||||||
return (userNameLowerCase === currentUserName.toLowerCase());
|
return (userNameLowerCase === currentUserName.toLowerCase());
|
||||||
});
|
});
|
||||||
|
const apiKey = await getApiKey(userNameLowerCase);
|
||||||
userObject = {
|
userObject = {
|
||||||
userName: userNameLowerCase,
|
userName: userNameLowerCase,
|
||||||
userProperties: {
|
userProperties: {
|
||||||
canUpdate,
|
canUpdate,
|
||||||
isAdmin
|
isAdmin,
|
||||||
|
apiKey
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import * as authenticationFunctions from "../helpers/functions.authentication.js
|
||||||
|
|
||||||
import { useTestDatabases } from "../data/databasePaths.js";
|
import { useTestDatabases } from "../data/databasePaths.js";
|
||||||
|
|
||||||
|
import { getApiKey } from "../helpers/functions.api.js";
|
||||||
|
|
||||||
import type * as recordTypes from "../types/recordTypes";
|
import type * as recordTypes from "../types/recordTypes";
|
||||||
|
|
||||||
export const router = Router();
|
export const router = Router();
|
||||||
|
|
@ -112,11 +114,14 @@ router
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const apiKey = await getApiKey(userNameLowerCase);
|
||||||
|
|
||||||
userObject = {
|
userObject = {
|
||||||
userName: userNameLowerCase,
|
userName: userNameLowerCase,
|
||||||
userProperties: {
|
userProperties: {
|
||||||
canUpdate,
|
canUpdate,
|
||||||
isAdmin
|
isAdmin,
|
||||||
|
apiKey
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ const user = {
|
||||||
userName: "import.unix",
|
userName: "import.unix",
|
||||||
userProperties: {
|
userProperties: {
|
||||||
canUpdate: true,
|
canUpdate: true,
|
||||||
isAdmin: false
|
isAdmin: false,
|
||||||
|
apiKey: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,8 @@ const user: recordTypes.PartialSession = {
|
||||||
userName: "import.unix",
|
userName: "import.unix",
|
||||||
userProperties: {
|
userProperties: {
|
||||||
canUpdate: true,
|
canUpdate: true,
|
||||||
isAdmin: false
|
isAdmin: false,
|
||||||
|
apiKey: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
"use strict";
|
export {};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,7 @@ export interface User {
|
||||||
export interface UserProperties {
|
export interface UserProperties {
|
||||||
canUpdate: boolean;
|
canUpdate: boolean;
|
||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
|
apiKey: string;
|
||||||
}
|
}
|
||||||
declare module "express-session" {
|
declare module "express-session" {
|
||||||
interface Session {
|
interface Session {
|
||||||
|
|
|
||||||
|
|
@ -337,6 +337,7 @@ export interface User {
|
||||||
export interface UserProperties {
|
export interface UserProperties {
|
||||||
canUpdate: boolean;
|
canUpdate: boolean;
|
||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
|
apiKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "express-session" {
|
declare module "express-session" {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue