@frogbotai/plugin-api-keys 0.28.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,24 +1,22 @@
1
1
  import { createApiKeysCollection } from './collection.js';
2
- import { createApiKeyStrategy } from './strategy.js';
2
+ import { apiKeyMeHook, apiKeyStrategyName, createApiKeyStrategy } from './strategy.js';
3
3
  export { ApiKeyServiceError, mintApiKey, revokeApiKey, rotateApiKey } from './server/services.js';
4
- export { createApiKeyToken, extractApiKeyToken, getApiKeyPrefix, hashApiKeyToken, } from './server/token.js';
4
+ export { createApiKeyToken, extractApiKeyToken, getApiKeyPrefix, hashApiKeyToken } from './server/token.js';
5
5
  export { isApiKeyStrategy } from './strategy.js';
6
6
  export function apiKeysPlugin(options = {}) {
7
- return (config) => {
7
+ return (config)=>{
8
8
  const authCollection = options.authCollection ?? 'users';
9
9
  const collectionSlug = options.collectionSlug ?? 'api-keys';
10
- const auth = config.collections.find((collection) => collection.slug === authCollection);
10
+ const auth = config.collections.find((collection)=>collection.slug === authCollection);
11
11
  if (!auth || auth.auth === undefined || auth.auth === false) {
12
12
  throw new Error(`[plugin-api-keys] Auth collection '${authCollection}' must exist and have auth enabled.`);
13
13
  }
14
- const existing = config.collections.find((collection) => collection.slug === collectionSlug);
15
- const usageLog = config.ai
16
- ? (config.collections.find((item) => item.usageLog === true) ?? {
17
- slug: 'usage-logs',
18
- usageLog: true,
19
- fields: [],
20
- })
21
- : undefined;
14
+ const existing = config.collections.find((collection)=>collection.slug === collectionSlug);
15
+ const usageLog = config.ai ? config.collections.find((item)=>item.usageLog === true) ?? {
16
+ slug: 'usage-logs',
17
+ usageLog: true,
18
+ fields: []
19
+ } : undefined;
22
20
  const collection = createApiKeysCollection({
23
21
  authCollection,
24
22
  collectionSlug,
@@ -26,73 +24,88 @@ export function apiKeysPlugin(options = {}) {
26
24
  usageCollection: usageLog?.slug,
27
25
  canRevokeAnyKey: options.canRevokeAnyKey,
28
26
  collection: options.collection,
29
- existing,
27
+ existing
30
28
  });
31
29
  const strategy = createApiKeyStrategy({
32
30
  authCollection,
33
31
  collectionSlug,
34
32
  headerNames: options.headerNames,
35
- tokenPrefix: options.tokenPrefix ?? 'fb',
33
+ tokenPrefix: options.tokenPrefix ?? 'fb'
36
34
  });
37
35
  const usageField = {
38
36
  name: 'apiKey',
39
37
  type: 'relationship',
40
38
  relationTo: collectionSlug,
41
- index: true,
39
+ index: true
42
40
  };
43
- const collections = config.collections.map((item) => {
41
+ const collections = config.collections.map((item)=>{
44
42
  let next = item;
45
- if (item.slug === collectionSlug)
46
- next = collection;
43
+ if (item.slug === collectionSlug) next = collection;
47
44
  if (item.slug === authCollection) {
48
45
  const authConfig = typeof next.auth === 'object' ? next.auth : {};
49
46
  next = {
50
47
  ...next,
51
- auth: { ...authConfig, strategies: [...(authConfig.strategies ?? []), strategy] },
48
+ auth: {
49
+ ...authConfig,
50
+ strategies: [
51
+ ...authConfig.strategies ?? [],
52
+ strategy
53
+ ]
54
+ },
55
+ hooks: {
56
+ ...next.hooks,
57
+ me: [
58
+ ...next.hooks?.me ?? [],
59
+ apiKeyMeHook
60
+ ]
61
+ }
52
62
  };
53
63
  }
54
- if (item === usageLog)
55
- next = { ...next, fields: [...next.fields, usageField] };
64
+ if (item === usageLog) next = {
65
+ ...next,
66
+ fields: [
67
+ ...next.fields,
68
+ usageField
69
+ ]
70
+ };
56
71
  return next;
57
72
  });
58
73
  return {
59
74
  ...config,
60
- settings: [
61
- ...(config.settings ?? []),
62
- {
63
- label: 'API Keys',
64
- path: 'api-keys',
65
- Component: {
66
- path: '@frogbotai/next/views#CollectionSettingsRedirect',
67
- serverProps: { collectionSlug },
68
- },
69
- access: collection.access?.read,
70
- },
71
- ],
72
75
  collections: [
73
76
  ...collections,
74
- ...(existing ? [] : [collection]),
75
- ...(usageLog && !config.collections.includes(usageLog)
76
- ? [{ ...usageLog, fields: [usageField] }]
77
- : []),
77
+ ...existing ? [] : [
78
+ collection
79
+ ],
80
+ ...usageLog && !config.collections.includes(usageLog) ? [
81
+ {
82
+ ...usageLog,
83
+ fields: [
84
+ usageField
85
+ ]
86
+ }
87
+ ] : []
78
88
  ],
79
- ...(config.ai && {
89
+ ...config.ai && {
80
90
  ai: {
81
91
  ...config.ai,
82
92
  hooks: {
83
93
  ...config.ai.hooks,
84
94
  beforeOperation: [
85
- ...(config.ai.hooks?.beforeOperation ?? []),
86
- ({ req, context }) => {
87
- if (req?.user && 'apiKeyId' in req.user && typeof req.user.apiKeyId === 'string') {
88
- context.usageFields = { apiKey: req.user.apiKeyId };
89
- }
90
- },
91
- ],
92
- },
93
- },
94
- }),
95
+ ...config.ai.hooks?.beforeOperation ?? [],
96
+ ({ req, context })=>{
97
+ const user = req?.user;
98
+ const apiKeyId = user?._strategy === apiKeyStrategyName && (typeof user.apiKeyId === 'string' || typeof user.apiKeyId === 'number') ? user.apiKeyId : undefined;
99
+ if (apiKeyId !== undefined) context.usageFields = {
100
+ apiKey: apiKeyId
101
+ };
102
+ }
103
+ ]
104
+ }
105
+ }
106
+ }
95
107
  };
96
108
  };
97
109
  }
110
+
98
111
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAOrD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAElG,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAWjD,MAAM,UAAU,aAAa,CAAC,UAAgC,EAAE;IAC9D,OAAO,CAAC,MAAM,EAAE,EAAE;QAChB,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC;QACzD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,UAAU,CAAC;QAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;QACzF,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CACb,sCAAsC,cAAc,qCAAqC,CAC1F,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;QAC7F,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE;YACxB,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI;gBAC5D,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,EAAE;aACX,CAAC;YACJ,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,UAAU,GAAG,uBAAuB,CAAC;YACzC,cAAc;YACd,cAAc;YACd,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;YACxC,eAAe,EAAE,QAAQ,EAAE,IAAI;YAC/B,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,QAAQ;SACT,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,oBAAoB,CAAC;YACpC,cAAc;YACd,cAAc;YACd,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;SACzC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,cAAuB;YAC7B,UAAU,EAAE,cAAc;YAC1B,KAAK,EAAE,IAAI;SACZ,CAAC;QACF,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAClD,IAAI,IAAI,GAAG,IAAI,CAAC;YAChB,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;gBAAE,IAAI,GAAG,UAAU,CAAC;YACpD,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACjC,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClE,IAAI,GAAG;oBACL,GAAG,IAAI;oBACP,IAAI,EAAE,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE;iBAClF,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,KAAK,QAAQ;gBAAE,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;YAChF,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QACH,OAAO;YACL,GAAG,MAAM;YACT,QAAQ,EAAE;gBACR,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;gBAC1B;oBACE,KAAK,EAAE,UAAU;oBACjB,IAAI,EAAE,UAAU;oBAChB,SAAS,EAAE;wBACT,IAAI,EAAE,kDAAkD;wBACxD,WAAW,EAAE,EAAE,cAAc,EAAE;qBAChC;oBACD,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI;iBAChC;aACF;YACD,WAAW,EAAE;gBACX,GAAG,WAAW;gBACd,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;gBACjC,GAAG,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;oBACpD,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;oBACzC,CAAC,CAAC,EAAE,CAAC;aACR;YACD,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI;gBACf,EAAE,EAAE;oBACF,GAAG,MAAM,CAAC,EAAE;oBACZ,KAAK,EAAE;wBACL,GAAG,MAAM,CAAC,EAAE,CAAC,KAAK;wBAClB,eAAe,EAAE;4BACf,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,IAAI,EAAE,CAAC;4BAC3C,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE;gCACnB,IAAI,GAAG,EAAE,IAAI,IAAI,UAAU,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oCACjF,OAAO,CAAC,WAAW,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gCACtD,CAAC;4BACH,CAAC;yBACF;qBACF;iBACF;aACF,CAAC;SACH,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["createApiKeysCollection","apiKeyMeHook","apiKeyStrategyName","createApiKeyStrategy","ApiKeyServiceError","mintApiKey","revokeApiKey","rotateApiKey","createApiKeyToken","extractApiKeyToken","getApiKeyPrefix","hashApiKeyToken","isApiKeyStrategy","apiKeysPlugin","options","config","authCollection","collectionSlug","auth","collections","find","collection","slug","undefined","Error","existing","usageLog","ai","item","fields","tokenPrefix","usageCollection","canRevokeAnyKey","strategy","headerNames","usageField","name","type","relationTo","index","map","next","authConfig","strategies","hooks","me","includes","beforeOperation","req","context","user","apiKeyId","_strategy","usageFields","apiKey"],"mappings":"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","file":"index.js"}
@@ -1,73 +1,108 @@
1
1
  import { createApiKeyToken, getApiKeyPrefix, hashApiKeyToken } from './token.js';
2
2
  export class ApiKeyServiceError extends Error {
3
3
  code;
4
- constructor(code) {
5
- super(code);
6
- this.code = code;
4
+ constructor(code){
5
+ super(code), this.code = code;
7
6
  }
8
7
  }
9
- async function mintForOwner({ req, collectionSlug, tokenPrefix, name, owner, }) {
10
- const token = createApiKeyToken({ tokenPrefix });
8
+ async function mintForOwner({ req, collectionSlug, tokenPrefix, name, owner }) {
9
+ const token = createApiKeyToken({
10
+ tokenPrefix
11
+ });
11
12
  const prefix = getApiKeyPrefix(token);
12
- const doc = (await req.frogbot.create({
13
+ const doc = await req.frogbot.create({
13
14
  collection: collectionSlug,
14
- data: { name, owner, prefix, tokenHash: hashApiKeyToken(token) },
15
+ data: {
16
+ name,
17
+ owner,
18
+ prefix,
19
+ tokenHash: hashApiKeyToken(token)
20
+ },
15
21
  overrideAccess: true,
16
- req,
17
- }));
18
- return { id: doc.id, name, prefix, token, createdAt: doc.createdAt };
22
+ req
23
+ });
24
+ return {
25
+ id: doc.id,
26
+ name,
27
+ prefix,
28
+ token,
29
+ createdAt: doc.createdAt
30
+ };
19
31
  }
20
32
  export async function mintApiKey(options) {
21
33
  const owner = options.req.user?.id;
22
- if (owner === undefined)
23
- throw new ApiKeyServiceError('authentication_required');
34
+ if (owner === undefined) throw new ApiKeyServiceError('authentication_required');
24
35
  return mintForOwner({
25
36
  req: options.req,
26
37
  collectionSlug: options.collectionSlug,
27
38
  tokenPrefix: options.tokenPrefix,
28
39
  name: options.name,
29
- owner,
40
+ owner
30
41
  });
31
42
  }
32
- export async function rotateApiKey({ req, collectionSlug, id, tokenPrefix, anyOwner, }) {
33
- const revoked = await revokeApiKey({ req, collectionSlug, id, anyOwner });
43
+ export async function rotateApiKey({ req, collectionSlug, id, tokenPrefix, anyOwner }) {
44
+ const revoked = await revokeApiKey({
45
+ req,
46
+ collectionSlug,
47
+ id,
48
+ anyOwner
49
+ });
34
50
  return mintForOwner({
35
51
  req,
36
52
  collectionSlug,
37
53
  tokenPrefix,
38
54
  name: revoked.name,
39
- owner: revoked.owner,
55
+ owner: revoked.owner
40
56
  });
41
57
  }
42
58
  export async function revokeApiKey({ req, collectionSlug, id, anyOwner }) {
43
59
  const owner = req.user?.id;
44
- if (owner === undefined)
45
- throw new ApiKeyServiceError('authentication_required');
60
+ if (owner === undefined) throw new ApiKeyServiceError('authentication_required');
46
61
  const result = await req.frogbot.find({
47
62
  collection: collectionSlug,
48
63
  depth: 0,
49
64
  limit: 1,
50
65
  overrideAccess: true,
51
66
  req,
52
- where: anyOwner
53
- ? { id: { equals: id } }
54
- : { and: [{ id: { equals: id } }, { owner: { equals: owner } }] },
67
+ where: anyOwner ? {
68
+ id: {
69
+ equals: id
70
+ }
71
+ } : {
72
+ and: [
73
+ {
74
+ id: {
75
+ equals: id
76
+ }
77
+ },
78
+ {
79
+ owner: {
80
+ equals: owner
81
+ }
82
+ }
83
+ ]
84
+ }
55
85
  });
56
86
  const key = result.docs[0];
57
- if (!key ||
58
- (typeof key.id !== 'string' && typeof key.id !== 'number') ||
59
- typeof key.name !== 'string' ||
60
- (typeof key.owner !== 'string' && typeof key.owner !== 'number')) {
87
+ if (!key || typeof key.id !== 'string' && typeof key.id !== 'number' || typeof key.name !== 'string' || typeof key.owner !== 'string' && typeof key.owner !== 'number') {
61
88
  throw new ApiKeyServiceError('not_found');
62
89
  }
63
90
  const revokedAt = typeof key.revokedAt === 'string' ? key.revokedAt : new Date().toISOString();
64
91
  await req.frogbot.update({
65
92
  collection: collectionSlug,
66
93
  id: key.id,
67
- data: { revokedAt },
94
+ data: {
95
+ revokedAt
96
+ },
68
97
  overrideAccess: true,
69
- req,
98
+ req
70
99
  });
71
- return { id: key.id, name: key.name, owner: key.owner, revokedAt };
100
+ return {
101
+ id: key.id,
102
+ name: key.name,
103
+ owner: key.owner,
104
+ revokedAt
105
+ };
72
106
  }
107
+
73
108
  //# sourceMappingURL=services.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/server/services.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/server/services.ts"],"names":["createApiKeyToken","getApiKeyPrefix","hashApiKeyToken","ApiKeyServiceError","Error","code","mintForOwner","req","collectionSlug","tokenPrefix","name","owner","token","prefix","doc","frogbot","create","collection","data","tokenHash","overrideAccess","id","createdAt","mintApiKey","options","user","undefined","rotateApiKey","anyOwner","revoked","revokeApiKey","result","find","depth","limit","where","equals","and","key","docs","revokedAt","Date","toISOString","update"],"mappings":"AAEA,SAASA,iBAAiB,EAAEC,eAAe,EAAEC,eAAe,QAAQ,aAAa;AAgBjF,OAAO,MAAMC,2BAA2BC;;IACtC,YAAY,AAAgBC,IAA6C,CAAE;QACzE,KAAK,CAACA,YADoBA,OAAAA;IAE5B;AACF;AAIA,eAAeC,aAAa,EAC1BC,GAAG,EACHC,cAAc,EACdC,WAAW,EACXC,IAAI,EACJC,KAAK,EACe;IACpB,MAAMC,QAAQZ,kBAAkB;QAAES;IAAY;IAC9C,MAAMI,SAASZ,gBAAgBW;IAC/B,MAAME,MAAO,MAAMP,IAAIQ,OAAO,CAACC,MAAM,CAAC;QACpCC,YAAYT;QACZU,MAAM;YAAER;YAAMC;YAAOE;YAAQM,WAAWjB,gBAAgBU;QAAO;QAC/DQ,gBAAgB;QAChBb;IACF;IACA,OAAO;QAAEc,IAAIP,IAAIO,EAAE;QAAEX;QAAMG;QAAQD;QAAOU,WAAWR,IAAIQ,SAAS;IAAC;AACrE;AAEA,OAAO,eAAeC,WAAWC,OAA0B;IACzD,MAAMb,QAAQa,QAAQjB,GAAG,CAACkB,IAAI,EAAEJ;IAChC,IAAIV,UAAUe,WAAW,MAAM,IAAIvB,mBAAmB;IACtD,OAAOG,aAAa;QAClBC,KAAKiB,QAAQjB,GAAG;QAChBC,gBAAgBgB,QAAQhB,cAAc;QACtCC,aAAae,QAAQf,WAAW;QAChCC,MAAMc,QAAQd,IAAI;QAClBC;IACF;AACF;AAIA,OAAO,eAAegB,aAAa,EACjCpB,GAAG,EACHC,cAAc,EACda,EAAE,EACFZ,WAAW,EACXmB,QAAQ,EACY;IACpB,MAAMC,UAAU,MAAMC,aAAa;QAAEvB;QAAKC;QAAgBa;QAAIO;IAAS;IACvE,OAAOtB,aAAa;QAClBC;QACAC;QACAC;QACAC,MAAMmB,QAAQnB,IAAI;QAClBC,OAAOkB,QAAQlB,KAAK;IACtB;AACF;AAEA,OAAO,eAAemB,aAAa,EAAEvB,GAAG,EAAEC,cAAc,EAAEa,EAAE,EAAEO,QAAQ,EAAuB;IAC3F,MAAMjB,QAAQJ,IAAIkB,IAAI,EAAEJ;IACxB,IAAIV,UAAUe,WAAW,MAAM,IAAIvB,mBAAmB;IACtD,MAAM4B,SAAS,MAAMxB,IAAIQ,OAAO,CAACiB,IAAI,CAAC;QACpCf,YAAYT;QACZyB,OAAO;QACPC,OAAO;QACPd,gBAAgB;QAChBb;QACA4B,OAAOP,WACH;YAAEP,IAAI;gBAAEe,QAAQf;YAAG;QAAE,IACrB;YAAEgB,KAAK;gBAAC;oBAAEhB,IAAI;wBAAEe,QAAQf;oBAAG;gBAAE;gBAAG;oBAAEV,OAAO;wBAAEyB,QAAQzB;oBAAM;gBAAE;aAAE;QAAC;IACpE;IACA,MAAM2B,MAAMP,OAAOQ,IAAI,CAAC,EAAE;IAC1B,IACE,CAACD,OACA,OAAOA,IAAIjB,EAAE,KAAK,YAAY,OAAOiB,IAAIjB,EAAE,KAAK,YACjD,OAAOiB,IAAI5B,IAAI,KAAK,YACnB,OAAO4B,IAAI3B,KAAK,KAAK,YAAY,OAAO2B,IAAI3B,KAAK,KAAK,UACvD;QACA,MAAM,IAAIR,mBAAmB;IAC/B;IACA,MAAMqC,YAAY,OAAOF,IAAIE,SAAS,KAAK,WAAWF,IAAIE,SAAS,GAAG,IAAIC,OAAOC,WAAW;IAC5F,MAAMnC,IAAIQ,OAAO,CAAC4B,MAAM,CAAC;QACvB1B,YAAYT;QACZa,IAAIiB,IAAIjB,EAAE;QACVH,MAAM;YAAEsB;QAAU;QAClBpB,gBAAgB;QAChBb;IACF;IACA,OAAO;QAAEc,IAAIiB,IAAIjB,EAAE;QAAEX,MAAM4B,IAAI5B,IAAI;QAAEC,OAAO2B,IAAI3B,KAAK;QAAE6B;IAAU;AACnE","file":"services.js"}
@@ -7,5 +7,5 @@ export type ApiKeyHeaderOptions = {
7
7
  export declare function createApiKeyToken({ tokenPrefix }?: ApiKeyTokenOptions): string;
8
8
  export declare function hashApiKeyToken(token: string): string;
9
9
  export declare function getApiKeyPrefix(token: string): string;
10
- export declare function extractApiKeyToken(headers: Headers, { headerNames }?: ApiKeyHeaderOptions): string | null;
10
+ export declare function extractApiKeyToken(headers: Headers, { headerNames, tokenPrefix }?: ApiKeyHeaderOptions & ApiKeyTokenOptions): string | null;
11
11
  //# sourceMappingURL=token.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/server/token.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAAE,WAAkB,EAAE,GAAE,kBAAuB,GAAG,MAAM,CAEzF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,EAAE,WAA2B,EAAE,GAAE,mBAAwB,GACxD,MAAM,GAAG,IAAI,CAWf"}
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/server/token.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAAE,WAAkB,EAAE,GAAE,kBAAuB,GAAG,MAAM,CAEzF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAQD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,EAAE,WAA2B,EAAE,WAAW,EAAE,GAAE,mBAAmB,GAAG,kBAAuB,GAC1F,MAAM,GAAG,IAAI,CAKf"}
@@ -8,16 +8,21 @@ export function hashApiKeyToken(token) {
8
8
  export function getApiKeyPrefix(token) {
9
9
  return token.slice(0, 12);
10
10
  }
11
- export function extractApiKeyToken(headers, { headerNames = ['x-api-key'] } = {}) {
12
- const authorization = headers.get('authorization');
13
- const bearer = authorization?.match(/^Bearer ([^\s]+)$/i)?.[1];
14
- if (bearer)
15
- return bearer;
16
- for (const headerName of headerNames) {
17
- const value = headers.get(headerName)?.trim();
18
- if (value && !/\s/.test(value))
19
- return value;
20
- }
21
- return null;
11
+ function isApiKeyToken(value, { tokenPrefix = 'fb' } = {}) {
12
+ const prefix = tokenPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
13
+ return new RegExp(`^${prefix}_[A-Za-z0-9_-]{43}$`).test(value);
22
14
  }
15
+ export function extractApiKeyToken(headers, { headerNames = [
16
+ 'x-api-key'
17
+ ], tokenPrefix } = {}) {
18
+ const bearer = headers.get('authorization')?.match(/^Bearer ([^\s]+)$/i)?.[1];
19
+ const candidates = [
20
+ bearer,
21
+ ...headerNames.map((headerName)=>headers.get(headerName)?.trim())
22
+ ];
23
+ return candidates.find((value)=>value && isApiKeyToken(value, {
24
+ tokenPrefix
25
+ })) ?? null;
26
+ }
27
+
23
28
  //# sourceMappingURL=token.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/server/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAUtD,MAAM,UAAU,iBAAiB,CAAC,EAAE,WAAW,GAAG,IAAI,KAAyB,EAAE;IAC/E,OAAO,GAAG,WAAW,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,OAAgB,EAChB,EAAE,WAAW,GAAG,CAAC,WAAW,CAAC,KAA0B,EAAE;IAEzD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,aAAa,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC;QAC9C,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IAC/C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"sources":["../../src/server/token.ts"],"names":["createHash","randomBytes","createApiKeyToken","tokenPrefix","toString","hashApiKeyToken","token","update","digest","getApiKeyPrefix","slice","isApiKeyToken","value","prefix","replace","RegExp","test","extractApiKeyToken","headers","headerNames","bearer","get","match","candidates","map","headerName","trim","find"],"mappings":"AAAA,SAASA,UAAU,EAAEC,WAAW,QAAQ,cAAc;AAUtD,OAAO,SAASC,kBAAkB,EAAEC,cAAc,IAAI,EAAsB,GAAG,CAAC,CAAC;IAC/E,OAAO,GAAGA,YAAY,CAAC,EAAEF,YAAY,IAAIG,QAAQ,CAAC,cAAc;AAClE;AAEA,OAAO,SAASC,gBAAgBC,KAAa;IAC3C,OAAON,WAAW,UAAUO,MAAM,CAACD,OAAOE,MAAM,CAAC;AACnD;AAEA,OAAO,SAASC,gBAAgBH,KAAa;IAC3C,OAAOA,MAAMI,KAAK,CAAC,GAAG;AACxB;AAEA,SAASC,cAAcC,KAAa,EAAE,EAAET,cAAc,IAAI,EAAsB,GAAG,CAAC,CAAC;IACnF,MAAMU,SAASV,YAAYW,OAAO,CAAC,uBAAuB;IAE1D,OAAO,IAAIC,OAAO,CAAC,CAAC,EAAEF,OAAO,mBAAmB,CAAC,EAAEG,IAAI,CAACJ;AAC1D;AAEA,OAAO,SAASK,mBACdC,OAAgB,EAChB,EAAEC,cAAc;IAAC;CAAY,EAAEhB,WAAW,EAA4C,GAAG,CAAC,CAAC;IAE3F,MAAMiB,SAASF,QAAQG,GAAG,CAAC,kBAAkBC,MAAM,uBAAuB,CAAC,EAAE;IAC7E,MAAMC,aAAa;QAACH;WAAWD,YAAYK,GAAG,CAAC,CAACC,aAAeP,QAAQG,GAAG,CAACI,aAAaC;KAAQ;IAEhG,OAAOH,WAAWI,IAAI,CAAC,CAACf,QAAUA,SAASD,cAAcC,OAAO;YAAET;QAAY,OAAO;AACvF","file":"token.js"}
@@ -1,12 +1,13 @@
1
- import type { AuthConfig } from 'frogbot';
2
- export type ApiKeyStrategy = NonNullable<AuthConfig['strategies']>[number];
1
+ import type { AuthStrategy, CollectionMeHook } from 'frogbot';
2
+ export declare const apiKeyStrategyName = "api-key";
3
3
  type StrategyOptions = {
4
4
  authCollection: string;
5
5
  collectionSlug: string;
6
6
  headerNames?: string[];
7
7
  tokenPrefix: string;
8
8
  };
9
- export declare function createApiKeyStrategy(options: StrategyOptions): ApiKeyStrategy;
10
- export declare function isApiKeyStrategy(strategy: ApiKeyStrategy): boolean;
9
+ export declare function createApiKeyStrategy(options: StrategyOptions): AuthStrategy;
10
+ export declare function isApiKeyStrategy(strategy: AuthStrategy): boolean;
11
+ export declare const apiKeyMeHook: CollectionMeHook;
11
12
  export {};
12
13
  //# sourceMappingURL=strategy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../src/strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAI3E,KAAK,eAAe,GAAG;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAiE7E;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAElE"}
1
+ {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../src/strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI9D,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAI5C,KAAK,eAAe,GAAG;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,YAAY,CA8D3E;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAEhE;AAED,eAAO,MAAM,YAAY,EAAE,gBAI1B,CAAC"}
package/dist/strategy.js CHANGED
@@ -1,54 +1,76 @@
1
1
  import { extractApiKeyToken, hashApiKeyToken } from './server/token.js';
2
+ export const apiKeyStrategyName = 'api-key';
2
3
  const apiKeyStrategies = new WeakSet();
3
4
  export function createApiKeyStrategy(options) {
4
5
  const { authCollection, collectionSlug, headerNames, tokenPrefix } = options;
5
6
  const strategy = {
6
- name: 'api-key',
7
- authenticate: async ({ headers, payload }) => {
8
- const token = extractApiKeyToken(headers, { headerNames });
9
- if (!token ||
10
- !new RegExp(`^${tokenPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}_[A-Za-z0-9_-]{43}$`).test(token)) {
11
- return { user: null };
12
- }
13
- const keys = await payload.find({
7
+ name: apiKeyStrategyName,
8
+ authenticate: async ({ frogbot, headers })=>{
9
+ const token = extractApiKeyToken(headers, {
10
+ headerNames,
11
+ tokenPrefix
12
+ });
13
+ if (!token) return {
14
+ user: null
15
+ };
16
+ const keys = await frogbot.find({
14
17
  collection: collectionSlug,
15
18
  depth: 0,
16
19
  limit: 1,
17
20
  overrideAccess: true,
18
21
  where: {
19
22
  and: [
20
- { tokenHash: { equals: hashApiKeyToken(token) } },
21
- { revokedAt: { exists: false } },
22
- ],
23
- },
23
+ {
24
+ tokenHash: {
25
+ equals: hashApiKeyToken(token)
26
+ }
27
+ },
28
+ {
29
+ revokedAt: {
30
+ exists: false
31
+ }
32
+ }
33
+ ]
34
+ }
24
35
  });
25
36
  const key = keys.docs[0];
26
- if (!key?.owner)
27
- return { user: null };
28
- const user = await payload
29
- .findByID({ collection: authCollection, id: key.owner, depth: 0, overrideAccess: true })
30
- .catch(() => null);
31
- if (!user)
32
- return { user: null };
33
- await payload.update({
37
+ if (!key || typeof key.id !== 'string' && typeof key.id !== 'number' || typeof key.owner !== 'string' && typeof key.owner !== 'number') {
38
+ return {
39
+ user: null
40
+ };
41
+ }
42
+ const user = await frogbot.findByID({
43
+ collection: authCollection,
44
+ id: key.owner,
45
+ depth: 0,
46
+ overrideAccess: true
47
+ }).catch(()=>null);
48
+ if (!user) return {
49
+ user: null
50
+ };
51
+ await frogbot.update({
34
52
  collection: collectionSlug,
35
53
  id: key.id,
36
- data: { lastUsedAt: new Date().toISOString() },
37
- overrideAccess: true,
54
+ data: {
55
+ lastUsedAt: new Date().toISOString()
56
+ },
57
+ overrideAccess: true
38
58
  });
39
59
  return {
40
60
  user: {
41
61
  ...user,
42
62
  collection: authCollection,
43
- _strategy: 'api-key',
63
+ _strategy: apiKeyStrategyName,
44
64
  apiKeyId: key.id,
45
- ...(key.capture !== undefined ? { capture: key.capture } : {}),
46
- ...(typeof key.captureSampleRate === 'number'
47
- ? { captureSampleRate: key.captureSampleRate }
48
- : {}),
49
- },
65
+ ...key.capture !== undefined ? {
66
+ capture: key.capture
67
+ } : {},
68
+ ...typeof key.captureSampleRate === 'number' ? {
69
+ captureSampleRate: key.captureSampleRate
70
+ } : {}
71
+ }
50
72
  };
51
- },
73
+ }
52
74
  };
53
75
  apiKeyStrategies.add(strategy);
54
76
  return strategy;
@@ -56,4 +78,11 @@ export function createApiKeyStrategy(options) {
56
78
  export function isApiKeyStrategy(strategy) {
57
79
  return apiKeyStrategies.has(strategy);
58
80
  }
81
+ export const apiKeyMeHook = ({ user })=>{
82
+ if (user?._strategy !== apiKeyStrategyName) return;
83
+ return {
84
+ user
85
+ };
86
+ };
87
+
59
88
  //# sourceMappingURL=strategy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"strategy.js","sourceRoot":"","sources":["../src/strategy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"sources":["../src/strategy.ts"],"names":["extractApiKeyToken","hashApiKeyToken","apiKeyStrategyName","apiKeyStrategies","WeakSet","createApiKeyStrategy","options","authCollection","collectionSlug","headerNames","tokenPrefix","strategy","name","authenticate","frogbot","headers","token","user","keys","find","collection","depth","limit","overrideAccess","where","and","tokenHash","equals","revokedAt","exists","key","docs","id","owner","findByID","catch","update","data","lastUsedAt","Date","toISOString","_strategy","apiKeyId","capture","undefined","captureSampleRate","add","isApiKeyStrategy","has","apiKeyMeHook"],"mappings":"AAEA,SAASA,kBAAkB,EAAEC,eAAe,QAAQ,oBAAoB;AAExE,OAAO,MAAMC,qBAAqB,UAAU;AAE5C,MAAMC,mBAAmB,IAAIC;AAS7B,OAAO,SAASC,qBAAqBC,OAAwB;IAC3D,MAAM,EAAEC,cAAc,EAAEC,cAAc,EAAEC,WAAW,EAAEC,WAAW,EAAE,GAAGJ;IACrE,MAAMK,WAAyB;QAC7BC,MAAMV;QACNW,cAAc,OAAO,EAAEC,OAAO,EAAEC,OAAO,EAAE;YACvC,MAAMC,QAAQhB,mBAAmBe,SAAS;gBAAEN;gBAAaC;YAAY;YAErE,IAAI,CAACM,OAAO,OAAO;gBAAEC,MAAM;YAAK;YAEhC,MAAMC,OAAO,MAAMJ,QAAQK,IAAI,CAAC;gBAC9BC,YAAYZ;gBACZa,OAAO;gBACPC,OAAO;gBACPC,gBAAgB;gBAChBC,OAAO;oBACLC,KAAK;wBACH;4BAAEC,WAAW;gCAAEC,QAAQ1B,gBAAgBe;4BAAO;wBAAE;wBAChD;4BAAEY,WAAW;gCAAEC,QAAQ;4BAAM;wBAAE;qBAChC;gBACH;YACF;YACA,MAAMC,MAAMZ,KAAKa,IAAI,CAAC,EAAE;YAExB,IACE,CAACD,OACA,OAAOA,IAAIE,EAAE,KAAK,YAAY,OAAOF,IAAIE,EAAE,KAAK,YAChD,OAAOF,IAAIG,KAAK,KAAK,YAAY,OAAOH,IAAIG,KAAK,KAAK,UACvD;gBACA,OAAO;oBAAEhB,MAAM;gBAAK;YACtB;YAEA,MAAMA,OAAO,MAAMH,QAChBoB,QAAQ,CAAC;gBAAEd,YAAYb;gBAAgByB,IAAIF,IAAIG,KAAK;gBAAEZ,OAAO;gBAAGE,gBAAgB;YAAK,GACrFY,KAAK,CAAC,IAAM;YAEf,IAAI,CAAClB,MAAM,OAAO;gBAAEA,MAAM;YAAK;YAE/B,MAAMH,QAAQsB,MAAM,CAAC;gBACnBhB,YAAYZ;gBACZwB,IAAIF,IAAIE,EAAE;gBACVK,MAAM;oBAAEC,YAAY,IAAIC,OAAOC,WAAW;gBAAG;gBAC7CjB,gBAAgB;YAClB;YAEA,OAAO;gBACLN,MAAM;oBACJ,GAAGA,IAAI;oBACPG,YAAYb;oBACZkC,WAAWvC;oBACXwC,UAAUZ,IAAIE,EAAE;oBAChB,GAAIF,IAAIa,OAAO,KAAKC,YAAY;wBAAED,SAASb,IAAIa,OAAO;oBAAC,IAAI,CAAC,CAAC;oBAC7D,GAAI,OAAOb,IAAIe,iBAAiB,KAAK,WACjC;wBAAEA,mBAAmBf,IAAIe,iBAAiB;oBAAC,IAC3C,CAAC,CAAC;gBACR;YACF;QACF;IACF;IAEA1C,iBAAiB2C,GAAG,CAACnC;IAErB,OAAOA;AACT;AAEA,OAAO,SAASoC,iBAAiBpC,QAAsB;IACrD,OAAOR,iBAAiB6C,GAAG,CAACrC;AAC9B;AAEA,OAAO,MAAMsC,eAAiC,CAAC,EAAEhC,IAAI,EAAE;IACrD,IAAIA,MAAMwB,cAAcvC,oBAAoB;IAE5C,OAAO;QAAEe;IAAK;AAChB,EAAE","file":"strategy.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frogbotai/plugin-api-keys",
3
- "version": "0.28.0",
3
+ "version": "0.30.0",
4
4
  "description": "Multiple named API keys for FrogBot.",
5
5
  "license": "MIT",
6
6
  "author": "Colby Gilbert",
@@ -38,8 +38,8 @@
38
38
  "@payloadcms/ui": "3.90.1",
39
39
  "react": "^19.0.1 || ^19.1.2 || ^19.2.1",
40
40
  "react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1",
41
- "@frogbotai/gateway": "0.28.0",
42
- "frogbot": "0.28.0"
41
+ "@frogbotai/gateway": "0.30.0",
42
+ "frogbot": "0.30.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@payloadcms/ui": "3.90.1",
@@ -48,15 +48,15 @@
48
48
  "react": "19.2.6",
49
49
  "react-dom": "19.2.6",
50
50
  "typescript": "5.6.2",
51
- "@frogbotai/gateway": "0.28.0",
52
- "frogbot": "0.28.0",
53
- "@frogbotai/plugin-roles": "0.28.0"
51
+ "@frogbotai/plugin-roles": "0.30.0",
52
+ "@frogbotai/gateway": "0.30.0",
53
+ "frogbot": "0.30.0"
54
54
  },
55
55
  "publishConfig": {
56
56
  "access": "public"
57
57
  },
58
58
  "scripts": {
59
- "build": "rm -rf dist && tsc -p tsconfig.json && cp src/client/styles.css dist/client/styles.css",
59
+ "build": "node ../../../scripts/build-package.mjs --assets css",
60
60
  "clean": "rm -rf dist",
61
61
  "typecheck": "tsc --noEmit"
62
62
  }