feat: Prefix api keys

This commit is contained in:
Tom Moor
2022-12-03 18:21:33 -05:00
parent 0f31d5b45f
commit d6d1eb4485
4 changed files with 36 additions and 3 deletions

View File

@@ -150,7 +150,7 @@ interface FormData {
}
function generateSigningSecret() {
return `olws_${randomstring.generate(32)}`;
return `ol_whs_${randomstring.generate(32)}`;
}
function WebhookSubscriptionForm({ handleSubmit, webhookSubscription }: Props) {

View File

@@ -61,7 +61,7 @@ export default function auth(options: AuthenticationOptions = {}) {
let user: User | null | undefined;
if (token) {
if (String(token).match(/^[\w]{38}$/)) {
if (ApiKey.match(String(token))) {
ctx.state.authType = AuthenticationType.API;
let apiKey;

View File

@@ -0,0 +1,20 @@
import randomstring from "randomstring";
import { buildApiKey } from "@server/test/factories";
import ApiKey from "./ApiKey";
describe("#ApiKey", () => {
describe("match", () => {
test("should match an API secret", async () => {
const apiKey = await buildApiKey({
name: "Dev",
});
expect(ApiKey.match(apiKey?.secret)).toBe(true);
expect(ApiKey.match(`${randomstring.generate(38)}`)).toBe(true);
});
test("should not match non secrets", async () => {
expect(ApiKey.match("123")).toBe(false);
expect(ApiKey.match("1234567890")).toBe(false);
});
});
});

View File

@@ -15,6 +15,8 @@ import Length from "./validators/Length";
@Table({ tableName: "apiKeys", modelName: "apiKey" })
@Fix
class ApiKey extends ParanoidModel {
static prefix = "ol_api_";
@Length({
min: 3,
max: 255,
@@ -32,10 +34,21 @@ class ApiKey extends ParanoidModel {
@BeforeValidate
static async generateSecret(model: ApiKey) {
if (!model.secret) {
model.secret = randomstring.generate(38);
model.secret = `${ApiKey.prefix}${randomstring.generate(38)}`;
}
}
/**
* Validates that the input touch could be an API key, this does not check
* that the key exists in the database.
*
* @param text The text to validate
* @returns True if likely an API key
*/
static match(text: string) {
return !!text.replace(ApiKey.prefix, "").match(/^[\w]{38}$/);
}
// associations
@BelongsTo(() => User, "userId")