Skip to content

Commit

Permalink
fix: key creation and default prefix (#2816)
Browse files Browse the repository at this point in the history
* feat: new filter logic

* fix: remove ununused hook

* fix: parsing logic

* [autofix.ci] apply automated fixes

* chore: remove log

* chore: revert flag

* feat: add ui for logs search

* fix: input for search

* feat: add structured query parsing

* feat: allow parsing multiple search

* chore: run formatter

* [autofix.ci] apply automated fixes

* chore: fix build issue

* fix: build issue

* fix: build error

* feat: give preselected ai queries for users

* refactor: common functions into a hook

* refactor: checkbox component and selection logic

* refactor: allow easier filter navigation

* refactor: add full keyboard navigation for selected filters

* fix: key creation and default prefix assignment

* [autofix.ci] apply automated fixes

* fix: PR comments

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
ogzhanolguncu and autofix-ci[bot] authored Jan 14, 2025
1 parent 57615c2 commit abf169d
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
45 changes: 45 additions & 0 deletions apps/api/src/routes/v1_keys_createKey.happy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { eq, schema } from "@unkey/db";
import { newId } from "@unkey/id";
import { IntegrationHarness } from "src/pkg/testutil/integration-harness";

import { KeyV1 } from "@unkey/keys";
import type { V1KeysCreateKeyRequest, V1KeysCreateKeyResponse } from "./v1_keys_createKey";

test("creates key", async (t) => {
Expand Down Expand Up @@ -34,6 +35,50 @@ test("creates key", async (t) => {
expect(found!.hash).toEqual(await sha256(res.body.key));
});

test("creates key with default prefix and bytes from keyAuth", async (t) => {
const expectedPrefix = "_prefix";
const expectedBytes = 66;

const h = await IntegrationHarness.init(t);
const root = await h.createRootKey([`api.${h.resources.userApi.id}.create_key`]);

await h.db.primary
.update(schema.keyAuth)
.set({
defaultPrefix: expectedPrefix,
defaultBytes: expectedBytes,
})
.where(eq(schema.keyAuth.id, h.resources.userKeyAuth.id));

// Make the request without specifying prefix or byteLength
const res = await h.post<V1KeysCreateKeyRequest, V1KeysCreateKeyResponse>({
url: "/v1/keys.createKey",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${root.key}`,
},
body: {
apiId: h.resources.userApi.id,
enabled: true,
},
});

expect(res.status, `expected 200, received: ${JSON.stringify(res, null, 2)}`).toBe(200);

const found = await h.db.primary.query.keys.findFirst({
where: (table, { eq }) => eq(table.id, res.body.keyId),
});

const referenceKey = new KeyV1({
byteLength: expectedBytes,
prefix: expectedPrefix,
}).toString();

expect(found).toBeDefined();
expect(found!.start).toEqual(referenceKey.slice(0, 5));
expect(found!.hash).toEqual(await sha256(res.body.key));
});

describe("with enabled flag", () => {
describe("not set", () => {
test("should still create an enabled key", async (t) => {
Expand Down
7 changes: 5 additions & 2 deletions apps/api/src/routes/v1_keys_createKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ export const registerV1KeysCreateKey = (app: App) =>
})) ?? null
);
});

if (err) {
throw new UnkeyApiError({
code: "INTERNAL_SERVER_ERROR",
Expand Down Expand Up @@ -350,10 +351,12 @@ export const registerV1KeysCreateKey = (app: App) =>
apiId: api.id,
});
}

const secret = new KeyV1({
byteLength: req.byteLength ?? 16,
prefix: req.prefix,
byteLength: req.byteLength ?? api.keyAuth?.defaultBytes ?? 16,
prefix: req.prefix ?? (api.keyAuth?.defaultPrefix as string | undefined),
}).toString();

const start = secret.slice(0, (req.prefix?.length ?? 0) + 5);
const kId = newId("key");
const hash = await sha256(secret.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,18 @@ export const CreateKey = ({ apiId, keyAuthId, defaultBytes, defaultPrefix }: Pro
});

async function onSubmit(values: z.infer<typeof formSchema>) {
if (values.limit?.refill?.interval !== "none" && !values.limit?.refill?.amount) {
if (
values.limitEnabled &&
values.limit?.refill?.interval !== "none" &&
!values.limit?.refill?.amount
) {
form.setError("limit.refill.amount", {
type: "manual",
message: "Please enter a value if interval is selected",
});
return;
}

if (!values.expireEnabled) {
delete values.expires;
}
Expand Down

0 comments on commit abf169d

Please sign in to comment.