feat: Prefix api keys
This commit is contained in:
@@ -150,7 +150,7 @@ interface FormData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generateSigningSecret() {
|
function generateSigningSecret() {
|
||||||
return `olws_${randomstring.generate(32)}`;
|
return `ol_whs_${randomstring.generate(32)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function WebhookSubscriptionForm({ handleSubmit, webhookSubscription }: Props) {
|
function WebhookSubscriptionForm({ handleSubmit, webhookSubscription }: Props) {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export default function auth(options: AuthenticationOptions = {}) {
|
|||||||
let user: User | null | undefined;
|
let user: User | null | undefined;
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
if (String(token).match(/^[\w]{38}$/)) {
|
if (ApiKey.match(String(token))) {
|
||||||
ctx.state.authType = AuthenticationType.API;
|
ctx.state.authType = AuthenticationType.API;
|
||||||
let apiKey;
|
let apiKey;
|
||||||
|
|
||||||
|
|||||||
20
server/models/ApiKey.test.ts
Normal file
20
server/models/ApiKey.test.ts
Normal 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -15,6 +15,8 @@ import Length from "./validators/Length";
|
|||||||
@Table({ tableName: "apiKeys", modelName: "apiKey" })
|
@Table({ tableName: "apiKeys", modelName: "apiKey" })
|
||||||
@Fix
|
@Fix
|
||||||
class ApiKey extends ParanoidModel {
|
class ApiKey extends ParanoidModel {
|
||||||
|
static prefix = "ol_api_";
|
||||||
|
|
||||||
@Length({
|
@Length({
|
||||||
min: 3,
|
min: 3,
|
||||||
max: 255,
|
max: 255,
|
||||||
@@ -32,10 +34,21 @@ class ApiKey extends ParanoidModel {
|
|||||||
@BeforeValidate
|
@BeforeValidate
|
||||||
static async generateSecret(model: ApiKey) {
|
static async generateSecret(model: ApiKey) {
|
||||||
if (!model.secret) {
|
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
|
// associations
|
||||||
|
|
||||||
@BelongsTo(() => User, "userId")
|
@BelongsTo(() => User, "userId")
|
||||||
|
|||||||
Reference in New Issue
Block a user