@bivola/refresh-auth 1.1.1 → 1.1.2

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.
@@ -36,7 +36,7 @@ export const loginEndpoint = (options)=>({
36
36
  });
37
37
  },
38
38
  method: 'post',
39
- path: `${options.entity_slug}/auth/login`
39
+ path: `/${options.entity_slug}/auth/login`
40
40
  });
41
41
 
42
42
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/endpoints/login.ts"],"sourcesContent":["import type { Endpoint } from 'payload'\n\nimport type { AuthRefreshPluginOptions } from '../index'\n\nimport { createRefreshToken } from '../utils/crypto'\nimport { getRequestMeta } from '../utils/getRequestMeta'\n\ntype LoginEndpointOptions = Pick<\n AuthRefreshPluginOptions,\n 'entity_slug' | 'identifier_field' | 'pepper' | 'refreshTokenTTL'\n>\n\nexport const loginEndpoint = (options: LoginEndpointOptions): Endpoint => ({\n handler: async (req) => {\n const { deviceId, identifier, password } = (await req.json?.()) || {}\n\n if (!identifier || !password) {\n return Response.json({ message: 'Identifier and password are required.' }, { status: 400 })\n }\n\n const login = await req.payload.login({\n collection: options.entity_slug,\n data: {\n [options.identifier_field]: identifier,\n password,\n } as any,\n })\n\n const { token, tokenHash } = createRefreshToken(options.pepper)\n\n await req.payload.create({\n collection: 'refresh-tokens',\n data: {\n deviceId,\n entity: login.user.id,\n expiresAt: new Date(Date.now() + options.refreshTokenTTL * 24 * 60 * 60 * 1000),\n lastUsedAt: new Date(),\n tokenHash,\n ...getRequestMeta(req),\n },\n })\n\n return Response.json({\n access_token: login.token,\n refresh_token: token,\n user: login.user,\n })\n },\n method: 'post',\n path: `${options.entity_slug}/auth/login`,\n})\n"],"names":["createRefreshToken","getRequestMeta","loginEndpoint","options","handler","req","deviceId","identifier","password","json","Response","message","status","login","payload","collection","entity_slug","data","identifier_field","token","tokenHash","pepper","create","entity","user","id","expiresAt","Date","now","refreshTokenTTL","lastUsedAt","access_token","refresh_token","method","path"],"mappings":"AAIA,SAASA,kBAAkB,QAAQ,kBAAiB;AACpD,SAASC,cAAc,QAAQ,0BAAyB;AAOxD,OAAO,MAAMC,gBAAgB,CAACC,UAA6C,CAAA;QACzEC,SAAS,OAAOC;YACd,MAAM,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,QAAQ,EAAE,GAAG,AAAC,MAAMH,IAAII,IAAI,QAAS,CAAC;YAEpE,IAAI,CAACF,cAAc,CAACC,UAAU;gBAC5B,OAAOE,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAwC,GAAG;oBAAEC,QAAQ;gBAAI;YAC3F;YAEA,MAAMC,QAAQ,MAAMR,IAAIS,OAAO,CAACD,KAAK,CAAC;gBACpCE,YAAYZ,QAAQa,WAAW;gBAC/BC,MAAM;oBACJ,CAACd,QAAQe,gBAAgB,CAAC,EAAEX;oBAC5BC;gBACF;YACF;YAEA,MAAM,EAAEW,KAAK,EAAEC,SAAS,EAAE,GAAGpB,mBAAmBG,QAAQkB,MAAM;YAE9D,MAAMhB,IAAIS,OAAO,CAACQ,MAAM,CAAC;gBACvBP,YAAY;gBACZE,MAAM;oBACJX;oBACAiB,QAAQV,MAAMW,IAAI,CAACC,EAAE;oBACrBC,WAAW,IAAIC,KAAKA,KAAKC,GAAG,KAAKzB,QAAQ0B,eAAe,GAAG,KAAK,KAAK,KAAK;oBAC1EC,YAAY,IAAIH;oBAChBP;oBACA,GAAGnB,eAAeI,IAAI;gBACxB;YACF;YAEA,OAAOK,SAASD,IAAI,CAAC;gBACnBsB,cAAclB,MAAMM,KAAK;gBACzBa,eAAeb;gBACfK,MAAMX,MAAMW,IAAI;YAClB;QACF;QACAS,QAAQ;QACRC,MAAM,GAAG/B,QAAQa,WAAW,CAAC,WAAW,CAAC;IAC3C,CAAA,EAAE"}
1
+ {"version":3,"sources":["../../src/endpoints/login.ts"],"sourcesContent":["import type { Endpoint } from 'payload'\n\nimport type { AuthRefreshPluginOptions } from '../index'\n\nimport { createRefreshToken } from '../utils/crypto'\nimport { getRequestMeta } from '../utils/getRequestMeta'\n\ntype LoginEndpointOptions = Pick<\n AuthRefreshPluginOptions,\n 'entity_slug' | 'identifier_field' | 'pepper' | 'refreshTokenTTL'\n>\n\nexport const loginEndpoint = (options: LoginEndpointOptions): Endpoint => ({\n handler: async (req) => {\n const { deviceId, identifier, password } = (await req.json?.()) || {}\n\n if (!identifier || !password) {\n return Response.json({ message: 'Identifier and password are required.' }, { status: 400 })\n }\n\n const login = await req.payload.login({\n collection: options.entity_slug,\n data: {\n [options.identifier_field]: identifier,\n password,\n } as any,\n })\n\n const { token, tokenHash } = createRefreshToken(options.pepper)\n\n await req.payload.create({\n collection: 'refresh-tokens',\n data: {\n deviceId,\n entity: login.user.id,\n expiresAt: new Date(Date.now() + options.refreshTokenTTL * 24 * 60 * 60 * 1000),\n lastUsedAt: new Date(),\n tokenHash,\n ...getRequestMeta(req),\n },\n })\n\n return Response.json({\n access_token: login.token,\n refresh_token: token,\n user: login.user,\n })\n },\n method: 'post',\n path: `/${options.entity_slug}/auth/login`,\n})\n"],"names":["createRefreshToken","getRequestMeta","loginEndpoint","options","handler","req","deviceId","identifier","password","json","Response","message","status","login","payload","collection","entity_slug","data","identifier_field","token","tokenHash","pepper","create","entity","user","id","expiresAt","Date","now","refreshTokenTTL","lastUsedAt","access_token","refresh_token","method","path"],"mappings":"AAIA,SAASA,kBAAkB,QAAQ,kBAAiB;AACpD,SAASC,cAAc,QAAQ,0BAAyB;AAOxD,OAAO,MAAMC,gBAAgB,CAACC,UAA6C,CAAA;QACzEC,SAAS,OAAOC;YACd,MAAM,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,QAAQ,EAAE,GAAG,AAAC,MAAMH,IAAII,IAAI,QAAS,CAAC;YAEpE,IAAI,CAACF,cAAc,CAACC,UAAU;gBAC5B,OAAOE,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAwC,GAAG;oBAAEC,QAAQ;gBAAI;YAC3F;YAEA,MAAMC,QAAQ,MAAMR,IAAIS,OAAO,CAACD,KAAK,CAAC;gBACpCE,YAAYZ,QAAQa,WAAW;gBAC/BC,MAAM;oBACJ,CAACd,QAAQe,gBAAgB,CAAC,EAAEX;oBAC5BC;gBACF;YACF;YAEA,MAAM,EAAEW,KAAK,EAAEC,SAAS,EAAE,GAAGpB,mBAAmBG,QAAQkB,MAAM;YAE9D,MAAMhB,IAAIS,OAAO,CAACQ,MAAM,CAAC;gBACvBP,YAAY;gBACZE,MAAM;oBACJX;oBACAiB,QAAQV,MAAMW,IAAI,CAACC,EAAE;oBACrBC,WAAW,IAAIC,KAAKA,KAAKC,GAAG,KAAKzB,QAAQ0B,eAAe,GAAG,KAAK,KAAK,KAAK;oBAC1EC,YAAY,IAAIH;oBAChBP;oBACA,GAAGnB,eAAeI,IAAI;gBACxB;YACF;YAEA,OAAOK,SAASD,IAAI,CAAC;gBACnBsB,cAAclB,MAAMM,KAAK;gBACzBa,eAAeb;gBACfK,MAAMX,MAAMW,IAAI;YAClB;QACF;QACAS,QAAQ;QACRC,MAAM,CAAC,CAAC,EAAE/B,QAAQa,WAAW,CAAC,WAAW,CAAC;IAC5C,CAAA,EAAE"}
@@ -1,5 +1,5 @@
1
1
  import type { Endpoint } from 'payload';
2
2
  import type { AuthRefreshPluginOptions } from '../index';
3
- type LogoutEndpointOptions = Pick<AuthRefreshPluginOptions, 'pepper'>;
3
+ type LogoutEndpointOptions = Pick<AuthRefreshPluginOptions, 'entity_slug' | 'pepper'>;
4
4
  export declare const logoutEndpoint: (options: LogoutEndpointOptions) => Endpoint;
5
5
  export {};
@@ -38,7 +38,7 @@ export const logoutEndpoint = (options)=>({
38
38
  });
39
39
  },
40
40
  method: 'post',
41
- path: '/auth/logout'
41
+ path: `/auth/${options.entity_slug}/logout`
42
42
  });
43
43
 
44
44
  //# sourceMappingURL=logout.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/endpoints/logout.ts"],"sourcesContent":["import type { Endpoint } from 'payload'\n\nimport type { AuthRefreshPluginOptions } from '../index'\n\nimport { RevocationReason } from '../collections/refreshTokens'\nimport { hashToken } from '../utils/crypto'\n\ntype LogoutEndpointOptions = Pick<AuthRefreshPluginOptions, 'pepper'>\n\nexport const logoutEndpoint = (options: LogoutEndpointOptions): Endpoint => ({\n handler: async (req) => {\n const { refresh_token } = (await req.json?.()) || {}\n\n if (!refresh_token) {\n return Response.json({ message: 'refreshToken is required to logout.' }, { status: 400 })\n }\n\n const tokenHash = hashToken(refresh_token, options.pepper)\n const result = await req.payload.find({\n collection: 'refresh-tokens',\n where: { tokenHash: { equals: tokenHash } },\n })\n\n if (!result?.docs?.length) {\n return new Response(null, { status: 204 })\n }\n\n const session = result.docs[0]\n\n await req.payload.update({\n id: session.id,\n collection: 'refresh-tokens',\n data: {\n revocationReason: RevocationReason.UserLogout,\n revokedAt: new Date(),\n },\n })\n\n return new Response(null, { status: 204 })\n },\n method: 'post',\n path: '/auth/logout',\n})\n"],"names":["RevocationReason","hashToken","logoutEndpoint","options","handler","req","refresh_token","json","Response","message","status","tokenHash","pepper","result","payload","find","collection","where","equals","docs","length","session","update","id","data","revocationReason","UserLogout","revokedAt","Date","method","path"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,+BAA8B;AAC/D,SAASC,SAAS,QAAQ,kBAAiB;AAI3C,OAAO,MAAMC,iBAAiB,CAACC,UAA8C,CAAA;QAC3EC,SAAS,OAAOC;YACd,MAAM,EAAEC,aAAa,EAAE,GAAG,AAAC,MAAMD,IAAIE,IAAI,QAAS,CAAC;YAEnD,IAAI,CAACD,eAAe;gBAClB,OAAOE,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAsC,GAAG;oBAAEC,QAAQ;gBAAI;YACzF;YAEA,MAAMC,YAAYV,UAAUK,eAAeH,QAAQS,MAAM;YACzD,MAAMC,SAAS,MAAMR,IAAIS,OAAO,CAACC,IAAI,CAAC;gBACpCC,YAAY;gBACZC,OAAO;oBAAEN,WAAW;wBAAEO,QAAQP;oBAAU;gBAAE;YAC5C;YAEA,IAAI,CAACE,QAAQM,MAAMC,QAAQ;gBACzB,OAAO,IAAIZ,SAAS,MAAM;oBAAEE,QAAQ;gBAAI;YAC1C;YAEA,MAAMW,UAAUR,OAAOM,IAAI,CAAC,EAAE;YAE9B,MAAMd,IAAIS,OAAO,CAACQ,MAAM,CAAC;gBACvBC,IAAIF,QAAQE,EAAE;gBACdP,YAAY;gBACZQ,MAAM;oBACJC,kBAAkBzB,iBAAiB0B,UAAU;oBAC7CC,WAAW,IAAIC;gBACjB;YACF;YAEA,OAAO,IAAIpB,SAAS,MAAM;gBAAEE,QAAQ;YAAI;QAC1C;QACAmB,QAAQ;QACRC,MAAM;IACR,CAAA,EAAE"}
1
+ {"version":3,"sources":["../../src/endpoints/logout.ts"],"sourcesContent":["import type { Endpoint } from 'payload'\n\nimport type { AuthRefreshPluginOptions } from '../index'\n\nimport { RevocationReason } from '../collections/refreshTokens'\nimport { hashToken } from '../utils/crypto'\n\ntype LogoutEndpointOptions = Pick<AuthRefreshPluginOptions, 'entity_slug' | 'pepper'>\n\nexport const logoutEndpoint = (options: LogoutEndpointOptions): Endpoint => ({\n handler: async (req) => {\n const { refresh_token } = (await req.json?.()) || {}\n\n if (!refresh_token) {\n return Response.json({ message: 'refreshToken is required to logout.' }, { status: 400 })\n }\n\n const tokenHash = hashToken(refresh_token, options.pepper)\n const result = await req.payload.find({\n collection: 'refresh-tokens',\n where: { tokenHash: { equals: tokenHash } },\n })\n\n if (!result?.docs?.length) {\n return new Response(null, { status: 204 })\n }\n\n const session = result.docs[0]\n\n await req.payload.update({\n id: session.id,\n collection: 'refresh-tokens',\n data: {\n revocationReason: RevocationReason.UserLogout,\n revokedAt: new Date(),\n },\n })\n\n return new Response(null, { status: 204 })\n },\n method: 'post',\n path: `/auth/${options.entity_slug}/logout`,\n})\n"],"names":["RevocationReason","hashToken","logoutEndpoint","options","handler","req","refresh_token","json","Response","message","status","tokenHash","pepper","result","payload","find","collection","where","equals","docs","length","session","update","id","data","revocationReason","UserLogout","revokedAt","Date","method","path","entity_slug"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,+BAA8B;AAC/D,SAASC,SAAS,QAAQ,kBAAiB;AAI3C,OAAO,MAAMC,iBAAiB,CAACC,UAA8C,CAAA;QAC3EC,SAAS,OAAOC;YACd,MAAM,EAAEC,aAAa,EAAE,GAAG,AAAC,MAAMD,IAAIE,IAAI,QAAS,CAAC;YAEnD,IAAI,CAACD,eAAe;gBAClB,OAAOE,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAsC,GAAG;oBAAEC,QAAQ;gBAAI;YACzF;YAEA,MAAMC,YAAYV,UAAUK,eAAeH,QAAQS,MAAM;YACzD,MAAMC,SAAS,MAAMR,IAAIS,OAAO,CAACC,IAAI,CAAC;gBACpCC,YAAY;gBACZC,OAAO;oBAAEN,WAAW;wBAAEO,QAAQP;oBAAU;gBAAE;YAC5C;YAEA,IAAI,CAACE,QAAQM,MAAMC,QAAQ;gBACzB,OAAO,IAAIZ,SAAS,MAAM;oBAAEE,QAAQ;gBAAI;YAC1C;YAEA,MAAMW,UAAUR,OAAOM,IAAI,CAAC,EAAE;YAE9B,MAAMd,IAAIS,OAAO,CAACQ,MAAM,CAAC;gBACvBC,IAAIF,QAAQE,EAAE;gBACdP,YAAY;gBACZQ,MAAM;oBACJC,kBAAkBzB,iBAAiB0B,UAAU;oBAC7CC,WAAW,IAAIC;gBACjB;YACF;YAEA,OAAO,IAAIpB,SAAS,MAAM;gBAAEE,QAAQ;YAAI;QAC1C;QACAmB,QAAQ;QACRC,MAAM,CAAC,MAAM,EAAE3B,QAAQ4B,WAAW,CAAC,OAAO,CAAC;IAC7C,CAAA,EAAE"}
@@ -86,7 +86,7 @@ export const refreshEndpoint = (options)=>({
86
86
  });
87
87
  },
88
88
  method: 'post',
89
- path: `${options.entity_slug}/auth/refresh`
89
+ path: `/${options.entity_slug}/auth/refresh`
90
90
  });
91
91
 
92
92
  //# sourceMappingURL=refresh.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/endpoints/refresh.ts"],"sourcesContent":["import type { Endpoint } from 'payload'\n\nimport type { AuthRefreshPluginOptions } from '../index'\n\nimport { RevocationReason } from '../collections/refreshTokens'\nimport { createRefreshToken, hashToken } from '../utils/crypto'\nimport { getRequestMeta } from '../utils/getRequestMeta'\nimport { signJWT } from '../utils/jwt'\n\ntype RefreshEndpointOptions = Pick<\n AuthRefreshPluginOptions,\n 'entity_slug' | 'identifier_field' | 'pepper' | 'refreshTokenTTL'\n>\n\nexport const refreshEndpoint = (options: RefreshEndpointOptions): Endpoint => ({\n handler: async (req) => {\n const { deviceId, refresh_token } = (await req.json?.()) || {}\n\n if (!refresh_token || !deviceId) {\n return Response.json(\n { message: 'Refresh token and device ID are required.' },\n { status: 400 },\n )\n }\n\n const result = await req.payload.find({\n collection: 'refresh-tokens',\n where: {\n tokenHash: {\n equals: hashToken(refresh_token, options.pepper),\n },\n },\n })\n\n if (!result?.docs?.length) {\n return Response.json({ message: 'Unauthorized.' }, { status: 401 })\n }\n\n const session = result.docs[0]\n\n if (session.deviceId !== deviceId || session.expiresAt < new Date() || session.revokedAt) {\n return Response.json({ message: 'Unauthorized.' }, { status: 401 })\n }\n\n if (session.rotatedAt) {\n await req.payload.update({\n id: session.id,\n collection: 'refresh-tokens',\n data: { revocationReason: RevocationReason.SuspiciousActivity, revokedAt: new Date() },\n })\n return Response.json({ message: 'Unauthorized.' }, { status: 401 })\n }\n\n const { token, tokenHash } = createRefreshToken(options.pepper)\n const now = new Date()\n\n const newSession = await req.payload.create({\n collection: 'refresh-tokens',\n data: {\n deviceId,\n entity: session.user,\n expiresAt: new Date(now.getTime() + options.refreshTokenTTL * 24 * 60 * 60 * 1000),\n lastUsedAt: now,\n tokenHash,\n ...getRequestMeta(req),\n },\n })\n\n await req.payload.update({\n id: session.id,\n collection: 'refresh-tokens',\n data: {\n lastUsedAt: now,\n replacedBy: newSession.id,\n revocationReason: RevocationReason.TokenRotation,\n rotatedAt: now,\n },\n })\n\n const accessJWT = signJWT({\n collectionId: session.user,\n collectionSlug: options.entity_slug,\n expiresIn: '15m',\n rawSecret: req.payload.secret,\n })\n\n return Response.json({\n access_token: accessJWT,\n refresh_token: token,\n user: session.user,\n })\n },\n method: 'post',\n path: `${options.entity_slug}/auth/refresh`,\n})\n"],"names":["RevocationReason","createRefreshToken","hashToken","getRequestMeta","signJWT","refreshEndpoint","options","handler","req","deviceId","refresh_token","json","Response","message","status","result","payload","find","collection","where","tokenHash","equals","pepper","docs","length","session","expiresAt","Date","revokedAt","rotatedAt","update","id","data","revocationReason","SuspiciousActivity","token","now","newSession","create","entity","user","getTime","refreshTokenTTL","lastUsedAt","replacedBy","TokenRotation","accessJWT","collectionId","collectionSlug","entity_slug","expiresIn","rawSecret","secret","access_token","method","path"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,+BAA8B;AAC/D,SAASC,kBAAkB,EAAEC,SAAS,QAAQ,kBAAiB;AAC/D,SAASC,cAAc,QAAQ,0BAAyB;AACxD,SAASC,OAAO,QAAQ,eAAc;AAOtC,OAAO,MAAMC,kBAAkB,CAACC,UAA+C,CAAA;QAC7EC,SAAS,OAAOC;YACd,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAE,GAAG,AAAC,MAAMF,IAAIG,IAAI,QAAS,CAAC;YAE7D,IAAI,CAACD,iBAAiB,CAACD,UAAU;gBAC/B,OAAOG,SAASD,IAAI,CAClB;oBAAEE,SAAS;gBAA4C,GACvD;oBAAEC,QAAQ;gBAAI;YAElB;YAEA,MAAMC,SAAS,MAAMP,IAAIQ,OAAO,CAACC,IAAI,CAAC;gBACpCC,YAAY;gBACZC,OAAO;oBACLC,WAAW;wBACTC,QAAQnB,UAAUQ,eAAeJ,QAAQgB,MAAM;oBACjD;gBACF;YACF;YAEA,IAAI,CAACP,QAAQQ,MAAMC,QAAQ;gBACzB,OAAOZ,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAgB,GAAG;oBAAEC,QAAQ;gBAAI;YACnE;YAEA,MAAMW,UAAUV,OAAOQ,IAAI,CAAC,EAAE;YAE9B,IAAIE,QAAQhB,QAAQ,KAAKA,YAAYgB,QAAQC,SAAS,GAAG,IAAIC,UAAUF,QAAQG,SAAS,EAAE;gBACxF,OAAOhB,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAgB,GAAG;oBAAEC,QAAQ;gBAAI;YACnE;YAEA,IAAIW,QAAQI,SAAS,EAAE;gBACrB,MAAMrB,IAAIQ,OAAO,CAACc,MAAM,CAAC;oBACvBC,IAAIN,QAAQM,EAAE;oBACdb,YAAY;oBACZc,MAAM;wBAAEC,kBAAkBjC,iBAAiBkC,kBAAkB;wBAAEN,WAAW,IAAID;oBAAO;gBACvF;gBACA,OAAOf,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAgB,GAAG;oBAAEC,QAAQ;gBAAI;YACnE;YAEA,MAAM,EAAEqB,KAAK,EAAEf,SAAS,EAAE,GAAGnB,mBAAmBK,QAAQgB,MAAM;YAC9D,MAAMc,MAAM,IAAIT;YAEhB,MAAMU,aAAa,MAAM7B,IAAIQ,OAAO,CAACsB,MAAM,CAAC;gBAC1CpB,YAAY;gBACZc,MAAM;oBACJvB;oBACA8B,QAAQd,QAAQe,IAAI;oBACpBd,WAAW,IAAIC,KAAKS,IAAIK,OAAO,KAAKnC,QAAQoC,eAAe,GAAG,KAAK,KAAK,KAAK;oBAC7EC,YAAYP;oBACZhB;oBACA,GAAGjB,eAAeK,IAAI;gBACxB;YACF;YAEA,MAAMA,IAAIQ,OAAO,CAACc,MAAM,CAAC;gBACvBC,IAAIN,QAAQM,EAAE;gBACdb,YAAY;gBACZc,MAAM;oBACJW,YAAYP;oBACZQ,YAAYP,WAAWN,EAAE;oBACzBE,kBAAkBjC,iBAAiB6C,aAAa;oBAChDhB,WAAWO;gBACb;YACF;YAEA,MAAMU,YAAY1C,QAAQ;gBACxB2C,cAActB,QAAQe,IAAI;gBAC1BQ,gBAAgB1C,QAAQ2C,WAAW;gBACnCC,WAAW;gBACXC,WAAW3C,IAAIQ,OAAO,CAACoC,MAAM;YAC/B;YAEA,OAAOxC,SAASD,IAAI,CAAC;gBACnB0C,cAAcP;gBACdpC,eAAeyB;gBACfK,MAAMf,QAAQe,IAAI;YACpB;QACF;QACAc,QAAQ;QACRC,MAAM,GAAGjD,QAAQ2C,WAAW,CAAC,aAAa,CAAC;IAC7C,CAAA,EAAE"}
1
+ {"version":3,"sources":["../../src/endpoints/refresh.ts"],"sourcesContent":["import type { Endpoint } from 'payload'\n\nimport type { AuthRefreshPluginOptions } from '../index'\n\nimport { RevocationReason } from '../collections/refreshTokens'\nimport { createRefreshToken, hashToken } from '../utils/crypto'\nimport { getRequestMeta } from '../utils/getRequestMeta'\nimport { signJWT } from '../utils/jwt'\n\ntype RefreshEndpointOptions = Pick<\n AuthRefreshPluginOptions,\n 'entity_slug' | 'identifier_field' | 'pepper' | 'refreshTokenTTL'\n>\n\nexport const refreshEndpoint = (options: RefreshEndpointOptions): Endpoint => ({\n handler: async (req) => {\n const { deviceId, refresh_token } = (await req.json?.()) || {}\n\n if (!refresh_token || !deviceId) {\n return Response.json(\n { message: 'Refresh token and device ID are required.' },\n { status: 400 },\n )\n }\n\n const result = await req.payload.find({\n collection: 'refresh-tokens',\n where: {\n tokenHash: {\n equals: hashToken(refresh_token, options.pepper),\n },\n },\n })\n\n if (!result?.docs?.length) {\n return Response.json({ message: 'Unauthorized.' }, { status: 401 })\n }\n\n const session = result.docs[0]\n\n if (session.deviceId !== deviceId || session.expiresAt < new Date() || session.revokedAt) {\n return Response.json({ message: 'Unauthorized.' }, { status: 401 })\n }\n\n if (session.rotatedAt) {\n await req.payload.update({\n id: session.id,\n collection: 'refresh-tokens',\n data: { revocationReason: RevocationReason.SuspiciousActivity, revokedAt: new Date() },\n })\n return Response.json({ message: 'Unauthorized.' }, { status: 401 })\n }\n\n const { token, tokenHash } = createRefreshToken(options.pepper)\n const now = new Date()\n\n const newSession = await req.payload.create({\n collection: 'refresh-tokens',\n data: {\n deviceId,\n entity: session.user,\n expiresAt: new Date(now.getTime() + options.refreshTokenTTL * 24 * 60 * 60 * 1000),\n lastUsedAt: now,\n tokenHash,\n ...getRequestMeta(req),\n },\n })\n\n await req.payload.update({\n id: session.id,\n collection: 'refresh-tokens',\n data: {\n lastUsedAt: now,\n replacedBy: newSession.id,\n revocationReason: RevocationReason.TokenRotation,\n rotatedAt: now,\n },\n })\n\n const accessJWT = signJWT({\n collectionId: session.user,\n collectionSlug: options.entity_slug,\n expiresIn: '15m',\n rawSecret: req.payload.secret,\n })\n\n return Response.json({\n access_token: accessJWT,\n refresh_token: token,\n user: session.user,\n })\n },\n method: 'post',\n path: `/${options.entity_slug}/auth/refresh`,\n})\n"],"names":["RevocationReason","createRefreshToken","hashToken","getRequestMeta","signJWT","refreshEndpoint","options","handler","req","deviceId","refresh_token","json","Response","message","status","result","payload","find","collection","where","tokenHash","equals","pepper","docs","length","session","expiresAt","Date","revokedAt","rotatedAt","update","id","data","revocationReason","SuspiciousActivity","token","now","newSession","create","entity","user","getTime","refreshTokenTTL","lastUsedAt","replacedBy","TokenRotation","accessJWT","collectionId","collectionSlug","entity_slug","expiresIn","rawSecret","secret","access_token","method","path"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,+BAA8B;AAC/D,SAASC,kBAAkB,EAAEC,SAAS,QAAQ,kBAAiB;AAC/D,SAASC,cAAc,QAAQ,0BAAyB;AACxD,SAASC,OAAO,QAAQ,eAAc;AAOtC,OAAO,MAAMC,kBAAkB,CAACC,UAA+C,CAAA;QAC7EC,SAAS,OAAOC;YACd,MAAM,EAAEC,QAAQ,EAAEC,aAAa,EAAE,GAAG,AAAC,MAAMF,IAAIG,IAAI,QAAS,CAAC;YAE7D,IAAI,CAACD,iBAAiB,CAACD,UAAU;gBAC/B,OAAOG,SAASD,IAAI,CAClB;oBAAEE,SAAS;gBAA4C,GACvD;oBAAEC,QAAQ;gBAAI;YAElB;YAEA,MAAMC,SAAS,MAAMP,IAAIQ,OAAO,CAACC,IAAI,CAAC;gBACpCC,YAAY;gBACZC,OAAO;oBACLC,WAAW;wBACTC,QAAQnB,UAAUQ,eAAeJ,QAAQgB,MAAM;oBACjD;gBACF;YACF;YAEA,IAAI,CAACP,QAAQQ,MAAMC,QAAQ;gBACzB,OAAOZ,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAgB,GAAG;oBAAEC,QAAQ;gBAAI;YACnE;YAEA,MAAMW,UAAUV,OAAOQ,IAAI,CAAC,EAAE;YAE9B,IAAIE,QAAQhB,QAAQ,KAAKA,YAAYgB,QAAQC,SAAS,GAAG,IAAIC,UAAUF,QAAQG,SAAS,EAAE;gBACxF,OAAOhB,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAgB,GAAG;oBAAEC,QAAQ;gBAAI;YACnE;YAEA,IAAIW,QAAQI,SAAS,EAAE;gBACrB,MAAMrB,IAAIQ,OAAO,CAACc,MAAM,CAAC;oBACvBC,IAAIN,QAAQM,EAAE;oBACdb,YAAY;oBACZc,MAAM;wBAAEC,kBAAkBjC,iBAAiBkC,kBAAkB;wBAAEN,WAAW,IAAID;oBAAO;gBACvF;gBACA,OAAOf,SAASD,IAAI,CAAC;oBAAEE,SAAS;gBAAgB,GAAG;oBAAEC,QAAQ;gBAAI;YACnE;YAEA,MAAM,EAAEqB,KAAK,EAAEf,SAAS,EAAE,GAAGnB,mBAAmBK,QAAQgB,MAAM;YAC9D,MAAMc,MAAM,IAAIT;YAEhB,MAAMU,aAAa,MAAM7B,IAAIQ,OAAO,CAACsB,MAAM,CAAC;gBAC1CpB,YAAY;gBACZc,MAAM;oBACJvB;oBACA8B,QAAQd,QAAQe,IAAI;oBACpBd,WAAW,IAAIC,KAAKS,IAAIK,OAAO,KAAKnC,QAAQoC,eAAe,GAAG,KAAK,KAAK,KAAK;oBAC7EC,YAAYP;oBACZhB;oBACA,GAAGjB,eAAeK,IAAI;gBACxB;YACF;YAEA,MAAMA,IAAIQ,OAAO,CAACc,MAAM,CAAC;gBACvBC,IAAIN,QAAQM,EAAE;gBACdb,YAAY;gBACZc,MAAM;oBACJW,YAAYP;oBACZQ,YAAYP,WAAWN,EAAE;oBACzBE,kBAAkBjC,iBAAiB6C,aAAa;oBAChDhB,WAAWO;gBACb;YACF;YAEA,MAAMU,YAAY1C,QAAQ;gBACxB2C,cAActB,QAAQe,IAAI;gBAC1BQ,gBAAgB1C,QAAQ2C,WAAW;gBACnCC,WAAW;gBACXC,WAAW3C,IAAIQ,OAAO,CAACoC,MAAM;YAC/B;YAEA,OAAOxC,SAASD,IAAI,CAAC;gBACnB0C,cAAcP;gBACdpC,eAAeyB;gBACfK,MAAMf,QAAQe,IAAI;YACpB;QACF;QACAc,QAAQ;QACRC,MAAM,CAAC,CAAC,EAAEjD,QAAQ2C,WAAW,CAAC,aAAa,CAAC;IAC9C,CAAA,EAAE"}
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ export const authRefreshPlugin = ({ entity_slug = 'users', identifier_field = 'e
26
26
  refreshTokenTTL
27
27
  }),
28
28
  logoutEndpoint({
29
+ entity_slug,
29
30
  pepper
30
31
  })
31
32
  ]
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config } from 'payload'\n\nimport { RefreshTokens } from './collections/refreshTokens'\nimport { loginEndpoint } from './endpoints/login'\nimport { logoutEndpoint } from './endpoints/logout'\nimport { refreshEndpoint } from './endpoints/refresh'\n\nexport type AuthRefreshPluginOptions = {\n entity_slug: string\n identifier_field: string\n pepper: string\n refreshTokenTTL: number\n}\n\nexport const authRefreshPlugin =\n ({\n entity_slug = 'users',\n identifier_field = 'email',\n pepper = 'default-pepper',\n refreshTokenTTL = 30,\n }: AuthRefreshPluginOptions): ((config: Config) => Config) =>\n (config) => {\n return {\n ...config,\n collections: [...(config.collections || []), RefreshTokens({ entity_slug })],\n endpoints: [\n ...(config.endpoints || []),\n loginEndpoint({ entity_slug, identifier_field, pepper, refreshTokenTTL }),\n refreshEndpoint({ entity_slug, identifier_field, pepper, refreshTokenTTL }),\n logoutEndpoint({ pepper }),\n ],\n }\n }\n"],"names":["RefreshTokens","loginEndpoint","logoutEndpoint","refreshEndpoint","authRefreshPlugin","entity_slug","identifier_field","pepper","refreshTokenTTL","config","collections","endpoints"],"mappings":"AAEA,SAASA,aAAa,QAAQ,8BAA6B;AAC3D,SAASC,aAAa,QAAQ,oBAAmB;AACjD,SAASC,cAAc,QAAQ,qBAAoB;AACnD,SAASC,eAAe,QAAQ,sBAAqB;AASrD,OAAO,MAAMC,oBACX,CAAC,EACCC,cAAc,OAAO,EACrBC,mBAAmB,OAAO,EAC1BC,SAAS,gBAAgB,EACzBC,kBAAkB,EAAE,EACK,GAC3B,CAACC;QACC,OAAO;YACL,GAAGA,MAAM;YACTC,aAAa;mBAAKD,OAAOC,WAAW,IAAI,EAAE;gBAAGV,cAAc;oBAAEK;gBAAY;aAAG;YAC5EM,WAAW;mBACLF,OAAOE,SAAS,IAAI,EAAE;gBAC1BV,cAAc;oBAAEI;oBAAaC;oBAAkBC;oBAAQC;gBAAgB;gBACvEL,gBAAgB;oBAAEE;oBAAaC;oBAAkBC;oBAAQC;gBAAgB;gBACzEN,eAAe;oBAAEK;gBAAO;aACzB;QACH;IACF,EAAC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config } from 'payload'\n\nimport { RefreshTokens } from './collections/refreshTokens'\nimport { loginEndpoint } from './endpoints/login'\nimport { logoutEndpoint } from './endpoints/logout'\nimport { refreshEndpoint } from './endpoints/refresh'\n\nexport type AuthRefreshPluginOptions = {\n entity_slug: string\n identifier_field: string\n pepper: string\n refreshTokenTTL: number\n}\n\nexport const authRefreshPlugin =\n ({\n entity_slug = 'users',\n identifier_field = 'email',\n pepper = 'default-pepper',\n refreshTokenTTL = 30,\n }: AuthRefreshPluginOptions): ((config: Config) => Config) =>\n (config) => {\n return {\n ...config,\n collections: [...(config.collections || []), RefreshTokens({ entity_slug })],\n endpoints: [\n ...(config.endpoints || []),\n loginEndpoint({ entity_slug, identifier_field, pepper, refreshTokenTTL }),\n refreshEndpoint({ entity_slug, identifier_field, pepper, refreshTokenTTL }),\n logoutEndpoint({ entity_slug, pepper }),\n ],\n }\n }\n"],"names":["RefreshTokens","loginEndpoint","logoutEndpoint","refreshEndpoint","authRefreshPlugin","entity_slug","identifier_field","pepper","refreshTokenTTL","config","collections","endpoints"],"mappings":"AAEA,SAASA,aAAa,QAAQ,8BAA6B;AAC3D,SAASC,aAAa,QAAQ,oBAAmB;AACjD,SAASC,cAAc,QAAQ,qBAAoB;AACnD,SAASC,eAAe,QAAQ,sBAAqB;AASrD,OAAO,MAAMC,oBACX,CAAC,EACCC,cAAc,OAAO,EACrBC,mBAAmB,OAAO,EAC1BC,SAAS,gBAAgB,EACzBC,kBAAkB,EAAE,EACK,GAC3B,CAACC;QACC,OAAO;YACL,GAAGA,MAAM;YACTC,aAAa;mBAAKD,OAAOC,WAAW,IAAI,EAAE;gBAAGV,cAAc;oBAAEK;gBAAY;aAAG;YAC5EM,WAAW;mBACLF,OAAOE,SAAS,IAAI,EAAE;gBAC1BV,cAAc;oBAAEI;oBAAaC;oBAAkBC;oBAAQC;gBAAgB;gBACvEL,gBAAgB;oBAAEE;oBAAaC;oBAAkBC;oBAAQC;gBAAgB;gBACzEN,eAAe;oBAAEG;oBAAaE;gBAAO;aACtC;QACH;IACF,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivola/refresh-auth",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "A blank template to get started with Payload 3.0",
5
5
  "license": "MIT",
6
6
  "type": "module",