orange-auth 0.1.0 → 0.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.
@@ -1,6 +1,9 @@
1
1
  declare global {
2
2
  type MaybePromise<T> = T | Promise<T>;
3
3
  }
4
+ /**
5
+ * General session type. This should be augmented to include your session's fields.
6
+ */
4
7
  export interface Session extends Record<string, unknown> {
5
8
  id: string;
6
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../src/@types/globals.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IACX,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,OAAQ,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACpD,EAAE,EAAE,MAAM,CAAC;CACd"}
1
+ {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../src/@types/globals.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IACX,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,OAAQ,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACpD,EAAE,EAAE,MAAM,CAAC;CACd"}
@@ -1,4 +1,11 @@
1
1
  import { type JwtPayload, type PublicKey, type Secret, type VerifyOptions } from "jsonwebtoken";
2
2
  export { sign } from "jsonwebtoken";
3
+ /**
4
+ * Promisified version of the jwt's verify function.
5
+ * @param token The user's token.
6
+ * @param secretOrPublicKey Your secret key, or a public key.
7
+ * @param options Jwt options.
8
+ * @returns The user's payload, or null on errors.
9
+ */
3
10
  export declare function verify<T extends JwtPayload = JwtPayload>(token: string, secretOrPublicKey: Secret | PublicKey, options?: VerifyOptions): Promise<T | null>;
4
11
  //# sourceMappingURL=jwt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/functions/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,aAAa,EACrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,wBAAgB,MAAM,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EACpD,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,MAAM,GAAG,SAAS,EACrC,OAAO,CAAC,EAAE,aAAa,qBAQ1B"}
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/functions/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,aAAa,EACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EACpD,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,MAAM,GAAG,SAAS,EACrC,OAAO,CAAC,EAAE,aAAa,qBAS1B"}
@@ -1,9 +1,18 @@
1
1
  import { verify as baseVerify, } from "jsonwebtoken";
2
+ // The sign function is fine as-is
2
3
  export { sign } from "jsonwebtoken";
4
+ /**
5
+ * Promisified version of the jwt's verify function.
6
+ * @param token The user's token.
7
+ * @param secretOrPublicKey Your secret key, or a public key.
8
+ * @param options Jwt options.
9
+ * @returns The user's payload, or null on errors.
10
+ */
3
11
  export function verify(token, secretOrPublicKey, options) {
4
12
  return new Promise((resolve) => {
5
13
  baseVerify(token, secretOrPublicKey, { ...options, complete: false }, (err, payload) => {
6
- if (err)
14
+ // In case of error, it is assumed as a malicious token, so we invalidate it.
15
+ if (err?.cause)
7
16
  resolve(null);
8
17
  resolve(payload);
9
18
  });
@@ -0,0 +1,4 @@
1
+ export * from "./lib";
2
+ export * from "./providers";
3
+ export * from "./strategies";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./lib";
2
+ export * from "./providers";
3
+ export * from "./strategies";
package/dist/lib.d.ts CHANGED
@@ -1,16 +1,58 @@
1
1
  import type { Session } from "./@types/globals";
2
2
  import type { IStrategy } from "./strategies/IStrategy";
3
3
  import type { IProvider } from "./providers/IProvider";
4
+ import { type SerializeOptions } from "cookie";
4
5
  type Maybe<T> = T | null | undefined;
6
+ /**
7
+ * Auth Configuration props.
8
+ */
5
9
  export type ConfigOptionsProps = Readonly<{
10
+ /**
11
+ * All the available providers.
12
+ * If multiple instance of a single provider are used, the order does matter.
13
+ */
6
14
  providers: IProvider[];
15
+ /**
16
+ * Your secret key.
17
+ */
7
18
  secret: string;
19
+ /**
20
+ * A custom name for the cookie.
21
+ * Otherwise, the default name will be `orange.auth`
22
+ */
8
23
  cookieName?: string;
24
+ /**
25
+ * The strategy to be used.
26
+ */
9
27
  strategy: IStrategy;
28
+ /**
29
+ * This should be the url path that your auth is set up on, including the action and provider variables.
30
+ * @example
31
+ * ```js
32
+ * const app = express();
33
+ *
34
+ * app.all("/api/auth/{*auth}", createHandler(CreateAuth)({
35
+ * basePath: "/api/auth/:action/:provider",
36
+ * ...
37
+ * }))
38
+ * ```
39
+ */
10
40
  basePath: string;
41
+ /**
42
+ * Cookie serialization options. see [MDN Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies)
43
+ */
44
+ cookieSettings?: SerializeOptions;
11
45
  }>;
12
- export type ConfigOptions = Required<Omit<ConfigOptionsProps, "basePath">>;
46
+ /**
47
+ * Internally used version of the options
48
+ */
49
+ export type __internal__Options = Required<Omit<ConfigOptionsProps, "basePath">>;
13
50
  export declare const CreateAuth: (config: ConfigOptionsProps) => (req: Request, _: Universal.Context, runtime: import("@universal-middleware/core").RuntimeAdapter) => Promise<Response>;
51
+ /**
52
+ * Access a user's session.
53
+ * @param req Something that has a `headers` field; either a Headers instance, or just a plain object.
54
+ * @returns A session if found and valid, or `null`.
55
+ */
14
56
  export declare const getSession: <T extends Session = Session>(req: {
15
57
  headers: Maybe<Headers | Record<string, string>>;
16
58
  }) => Promise<T | null> | null;
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAW,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGhE,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAErC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC,CAAC;AAI3E,eAAO,MAAM,UAAU,WAAa,kBAAkB,4HAgEU,CAAC;AAEjE,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,KAAK;IAAE,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,6BAYhH,CAAC"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAW,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAGpE,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAErC;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC;;;OAGG;IACH,SAAS,EAAE,SAAS,EAAE,CAAC;IAEvB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;;;;;;;OAWG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACrC,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC,CAAC;AAWjF,eAAO,MAAM,UAAU,WAAa,kBAAkB,4HA6EU,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,KAAK;IAAE,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,6BAehH,CAAC"}
package/dist/lib.js CHANGED
@@ -1,65 +1,96 @@
1
1
  import Cookies from "universal-cookie";
2
- import { find, isNil } from "lodash-es";
2
+ import { assign, find, isNil } from "lodash-es";
3
3
  import { serialize as cookie } from "cookie";
4
4
  import { params } from "@universal-middleware/core";
5
- let globalCfg;
6
- export const CreateAuth = ((config) => async (req, _, runtime) => {
7
- const { secret, strategy, cookieName, providers, basePath } = config;
8
- const routeParams = params(req, runtime, basePath);
9
- if (isNil(routeParams?.["action"]) || isNil(routeParams["provider"])) {
10
- throw new Error('[ERROR]: Base path is missing! Make sure to set the "basePath" variable in the auth\'s config.');
11
- }
5
+ // Default config, only set otherwise `assign` doesn't like it.
6
+ let globalCfg = {
7
+ cookieName: "orange.auth",
8
+ providers: [],
9
+ secret: crypto.randomUUID(),
10
+ strategy: null,
11
+ cookieSettings: {},
12
+ };
13
+ export const CreateAuth = ((config) => {
14
+ const { secret, strategy, cookieName, providers, cookieSettings, basePath } = config;
12
15
  if (isNil(secret)) {
13
16
  throw new Error('[ERROR]: Auth secret missing! Make sure to set the "secret" variable in the auth\'s config.');
14
17
  }
15
18
  if (isNil(strategy)) {
16
19
  throw new Error('[ERROR]: No strategy chosen! Make sure to set the "strategy" variable in the auth\'s config.');
17
20
  }
18
- globalCfg = {
21
+ // We set the global config on startup, and not on the route handler,
22
+ // otherwise a session cannot be accessed until someone logs in
23
+ assign(globalCfg, {
19
24
  cookieName: cookieName ?? "orange.auth",
20
25
  providers: providers ?? [],
21
26
  secret,
22
27
  strategy,
23
- };
24
- const path = routeParams["provider"];
25
- const provider = find(providers, (p) => p.ID === path);
26
- if (isNil(provider)) {
27
- return new Response("Page not found", { status: 404 });
28
- }
29
- switch (routeParams["action"]) {
30
- case "login": {
31
- const token = await provider.logIn(req, globalCfg).catch(() => null);
32
- if (isNil(token))
33
- return new Response(null, { status: 400 });
34
- const headers = new Headers();
35
- headers.set("Set-Cookie", cookie(globalCfg.cookieName, token, {
36
- path: "/",
37
- httpOnly: true,
38
- sameSite: "lax",
39
- secure: true,
40
- maxAge: 600,
41
- }));
42
- return new Response(null, { status: 200, headers });
43
- }
44
- case "logout": {
45
- await globalCfg.strategy.logOut(req, globalCfg);
46
- const headers = new Headers();
47
- headers.set("Set-Cookie", cookie(globalCfg.cookieName, ""));
48
- return new Response(null, { status: 200, headers });
28
+ cookieSettings: cookieSettings ?? {
29
+ path: "/",
30
+ httpOnly: true,
31
+ sameSite: "lax",
32
+ secure: true,
33
+ maxAge: 3600,
34
+ },
35
+ });
36
+ return async (req, _, runtime) => {
37
+ // Tries to get the action and provider info from the url
38
+ const routeParams = params(req, runtime, basePath);
39
+ if (isNil(routeParams?.["action"]) || isNil(routeParams["provider"])) {
40
+ throw new Error('[ERROR]: Base path is missing! Make sure to set the "basePath" variable in the auth\'s config.');
49
41
  }
50
- default:
42
+ // Finds the requested provider by name
43
+ const path = routeParams["provider"];
44
+ const provider = find(providers, (p) => p.ID === path);
45
+ if (isNil(provider)) {
51
46
  return new Response("Page not found", { status: 404 });
52
- }
47
+ }
48
+ // Handles each action independently
49
+ switch (routeParams["action"]) {
50
+ case "login": {
51
+ // Use the found provider to login
52
+ const token = await provider.logIn(req, globalCfg).catch(() => null);
53
+ // If failed, return Bad Request response
54
+ if (isNil(token))
55
+ return new Response(null, { status: 400 });
56
+ // Creates the set-cookie header
57
+ const headers = new Headers();
58
+ headers.set("Set-Cookie", cookie(globalCfg.cookieName, token, globalCfg.cookieSettings));
59
+ // And returns it
60
+ return new Response(null, { status: 200, headers });
61
+ }
62
+ case "logout": {
63
+ // Use the strategy to logout
64
+ await globalCfg.strategy.logOut(req, globalCfg);
65
+ // Clears the header.
66
+ const headers = new Headers();
67
+ headers.set("Set-Cookie", cookie(globalCfg.cookieName, ""));
68
+ // And send them
69
+ return new Response(null, { status: 200, headers });
70
+ }
71
+ default:
72
+ // If a wrong action is requested, return a 404
73
+ return new Response("Page not found", { status: 404 });
74
+ }
75
+ };
53
76
  });
77
+ /**
78
+ * Access a user's session.
79
+ * @param req Something that has a `headers` field; either a Headers instance, or just a plain object.
80
+ * @returns A session if found and valid, or `null`.
81
+ */
54
82
  export const getSession = (req) => {
55
83
  if (isNil(req.headers))
56
84
  return null;
85
+ // Find the correct cookie header
57
86
  const cookieHeader = req.headers instanceof Headers ? req.headers.get("cookie") : req.headers["cookie"];
58
87
  const cookie = new Cookies(cookieHeader);
59
88
  if (isNil(cookie))
60
89
  return null;
90
+ // Tries to extract the specific cookie.
61
91
  const token = cookie.get(globalCfg.cookieName);
62
92
  if (isNil(token))
63
93
  return null;
94
+ // Tries to deserialize it
64
95
  return globalCfg.strategy.deserialize(token, globalCfg);
65
96
  };
@@ -1,15 +1,34 @@
1
1
  import { IProvider } from "./IProvider";
2
- import type { ConfigOptions } from "../lib";
2
+ import type { __internal__Options } from "../lib";
3
3
  import type { Session } from "../@types/globals";
4
+ /**
5
+ * Configuration options of the Credentials provider
6
+ */
4
7
  export type CredentialsConfig<TCredentials extends string> = Readonly<{
8
+ /**
9
+ * The name of this provider, should not be changed unless you are
10
+ * using multiple instance of the same provider.
11
+ */
5
12
  name?: "credentials" | (string & {});
13
+ /**
14
+ * The available fields coming from the request containing credentials.
15
+ */
6
16
  credentials: TCredentials[];
17
+ /**
18
+ * Function that gets called when a user tries to login.
19
+ * This is where you should look inside your database for the user.
20
+ * @param credentials An object containing the credentials from the request's body.
21
+ * @returns A session object if a user is found, or `null`.
22
+ */
7
23
  authorize: (credentials: Record<TCredentials, string>) => MaybePromise<Session | null>;
8
24
  }>;
25
+ /**
26
+ * Provider used to login a user using basic credentials.
27
+ */
9
28
  export declare class Credentials<TCredentials extends string = string> extends IProvider {
10
29
  private config;
11
30
  constructor(config: CredentialsConfig<TCredentials>);
12
- getSession(req: Request, globalCfg: ConfigOptions): Promise<Session | null>;
13
- logIn(req: Request, globalCfg: ConfigOptions): Promise<string | null>;
31
+ getSession(): Promise<Session | null>;
32
+ logIn(req: Request, globalCfg: __internal__Options): Promise<string | null>;
14
33
  }
15
34
  //# sourceMappingURL=Credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Credentials.d.ts","sourceRoot":"","sources":["../../src/providers/Credentials.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,MAAM,iBAAiB,CAAC,YAAY,SAAS,MAAM,IAAI,QAAQ,CAAC;IAClE,IAAI,CAAC,EAAE,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACrC,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC1F,CAAC,CAAC;AAEH,qBAAa,WAAW,CAAC,YAAY,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,SAAS;IAC5E,OAAO,CAAC,MAAM,CAAkC;gBAEpC,MAAM,EAAE,iBAAiB,CAAC,YAAY,CAAC;IAK7B,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAS3E,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAQ9F"}
1
+ {"version":3,"file":"Credentials.d.ts","sourceRoot":"","sources":["../../src/providers/Credentials.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,YAAY,SAAS,MAAM,IAAI,QAAQ,CAAC;IAClE;;;OAGG;IACH,IAAI,CAAC,EAAE,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACrC;;OAEG;IACH,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B;;;;;OAKG;IACH,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC1F,CAAC,CAAC;AAEH;;GAEG;AACH,qBAAa,WAAW,CAAC,YAAY,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,SAAS;IAC5E,OAAO,CAAC,MAAM,CAAkC;gBAEpC,MAAM,EAAE,iBAAiB,CAAC,YAAY,CAAC;IAK7B,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIrC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAWpG"}
@@ -1,24 +1,25 @@
1
1
  import { isNil } from "lodash-es";
2
- import Cookies from "universal-cookie";
3
2
  import { IProvider } from "./IProvider";
3
+ /**
4
+ * Provider used to login a user using basic credentials.
5
+ */
4
6
  export class Credentials extends IProvider {
5
7
  config;
6
8
  constructor(config) {
7
9
  super("credentials");
8
10
  this.config = config;
9
11
  }
10
- async getSession(req, globalCfg) {
11
- const cookies = new Cookies(req.headers.get("cookie"));
12
- const token = cookies.get(globalCfg.cookieName);
13
- if (token == null)
14
- return null;
15
- return globalCfg.strategy.deserialize(token, globalCfg);
12
+ async getSession() {
13
+ throw new Error("This should never be used");
16
14
  }
17
15
  async logIn(req, globalCfg) {
16
+ // We assume the body is json here, might change that later to be more flexible
18
17
  const body = (await req.json());
18
+ // Calls the user defined authorize callback
19
19
  const session = await this.config.authorize(body);
20
20
  if (isNil(session))
21
21
  return null;
22
+ // Create a token
22
23
  return globalCfg.strategy.serialize(session, globalCfg);
23
24
  }
24
25
  }
@@ -1,12 +1,32 @@
1
- import type { ConfigOptions } from "../lib";
1
+ import type { __internal__Options } from "../lib";
2
2
  import type { Session } from "../@types/globals";
3
+ /**
4
+ * Available url callback actions.
5
+ */
3
6
  export type Actions = "login" | "logout";
7
+ /**
8
+ * Providers are used to implement certain services (E.g. facebook, github, credentials) as login methods.
9
+ * Every provider should inherit from this.
10
+ */
4
11
  declare abstract class IProvider {
5
- private __ID;
12
+ /**
13
+ * This is used to map a callback to a provider.
14
+ */
15
+ private readonly __ID;
6
16
  constructor(ID: string);
17
+ /**
18
+ * The provider ID.
19
+ */
7
20
  get ID(): string;
8
- abstract getSession(req: Request, globalCfg: ConfigOptions): Promise<Session | null>;
9
- abstract logIn(req: Request, globalCfg: ConfigOptions): Promise<string | null>;
21
+ /** @deprecated You can use the top level `getSession` instead. */
22
+ abstract getSession(req: Request, globalCfg: __internal__Options): Promise<Session | null>;
23
+ /**
24
+ * Login function. This is used to call all the login flows of each provider.
25
+ * For now, the request's body **MUST** be JSON.
26
+ * @param req The request object.
27
+ * @param globalCfg The global auth config.
28
+ */
29
+ abstract logIn(req: Request, globalCfg: __internal__Options): Promise<string | null>;
10
30
  }
11
31
  export { IProvider };
12
32
  //# sourceMappingURL=IProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IProvider.d.ts","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEzC,uBAAe,SAAS;IACpB,OAAO,CAAC,IAAI,CAAS;gBAET,EAAE,EAAE,MAAM;IAItB,IAAW,EAAE,IAAI,MAAM,CAEtB;aAEe,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;aAC3E,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CACxF;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"IProvider.d.ts","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEzC;;;GAGG;AACH,uBAAe,SAAS;IACpB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,EAAE,EAAE,MAAM;IAItB;;OAEG;IACH,IAAW,EAAE,IAAI,MAAM,CAEtB;IAED,kEAAkE;aAClD,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAEjG;;;;;OAKG;aACa,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAC9F;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -1,8 +1,18 @@
1
+ /**
2
+ * Providers are used to implement certain services (E.g. facebook, github, credentials) as login methods.
3
+ * Every provider should inherit from this.
4
+ */
1
5
  class IProvider {
6
+ /**
7
+ * This is used to map a callback to a provider.
8
+ */
2
9
  __ID;
3
10
  constructor(ID) {
4
11
  this.__ID = ID;
5
12
  }
13
+ /**
14
+ * The provider ID.
15
+ */
6
16
  get ID() {
7
17
  return this.__ID;
8
18
  }
@@ -0,0 +1,3 @@
1
+ export * from "./IProvider";
2
+ export * from "./Credentials";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./IProvider";
2
+ export * from "./Credentials";
@@ -1,9 +1,29 @@
1
- import type { ConfigOptions } from "../lib";
1
+ import type { __internal__Options } from "../lib";
2
2
  import { type Session } from "../@types/globals";
3
+ /**
4
+ * A strategy is used to handle the creation, validation and accessing a user's session.
5
+ */
3
6
  declare abstract class IStrategy {
4
- abstract serialize(session: Session, globalCfg: ConfigOptions): Promise<string>;
5
- abstract deserialize(token: string, globalCfg: ConfigOptions): Promise<Session | null>;
6
- abstract logOut(req: Request, globalCfg: ConfigOptions): Promise<void>;
7
+ /**
8
+ * Handles how a session token is generated.
9
+ * @param session The validated session object.
10
+ * @param globalCfg The global auth config.
11
+ * @returns A newly generated token that will be sent as a cookie.
12
+ */
13
+ abstract serialize(session: Session, globalCfg: __internal__Options): Promise<string>;
14
+ /**
15
+ * Handles how a token is validated and deserialized into a session object.
16
+ * @param token A user's token.
17
+ * @param globalCfg The global auth config.
18
+ * @returns A user's session if validated and found, else `null`.
19
+ */
20
+ abstract deserialize(token: string, globalCfg: __internal__Options): Promise<Session | null>;
21
+ /**
22
+ * Handles how a session is destroyed when a user is logging out.
23
+ * @param req The request object.
24
+ * @param globalCfg The global auth config.
25
+ */
26
+ abstract logOut(req: Request, globalCfg: __internal__Options): Promise<void>;
7
27
  }
8
28
  export { IStrategy };
9
29
  //# sourceMappingURL=IStrategy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IStrategy.d.ts","sourceRoot":"","sources":["../../src/strategies/IStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,uBAAe,SAAS;aACJ,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;aACtE,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;aAC7E,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAChF;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"IStrategy.d.ts","sourceRoot":"","sources":["../../src/strategies/IStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,uBAAe,SAAS;IACpB;;;;;OAKG;aACa,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IAE5F;;;;;OAKG;aACa,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAEnG;;;;OAIG;aACa,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;CACtF;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -1,4 +1,7 @@
1
1
  import {} from "../@types/globals";
2
+ /**
3
+ * A strategy is used to handle the creation, validation and accessing a user's session.
4
+ */
2
5
  class IStrategy {
3
6
  }
4
7
  export { IStrategy };
@@ -0,0 +1,3 @@
1
+ export * from "./jwt";
2
+ export * from "./IStrategy";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strategies/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./jwt";
2
+ export * from "./IStrategy";
@@ -1,12 +1,18 @@
1
1
  import { IStrategy } from "./IStrategy";
2
- import type { ConfigOptions } from "../lib";
2
+ import type { __internal__Options } from "../lib";
3
3
  import type { SignOptions } from "jsonwebtoken";
4
4
  import type { Session } from "../@types/globals";
5
+ /**
6
+ * Basic JWT strategy
7
+ */
5
8
  declare class JWT extends IStrategy {
9
+ /**
10
+ * Forwarded standard JWT options
11
+ */
6
12
  private signOptions;
7
13
  constructor(options?: SignOptions);
8
- serialize(session: Session, globalCfg: ConfigOptions): Promise<string>;
9
- deserialize(token: string, globalCfg: ConfigOptions): Promise<Session | null>;
14
+ serialize(session: Session, globalCfg: __internal__Options): Promise<string>;
15
+ deserialize(token: string, globalCfg: __internal__Options): Promise<Session | null>;
10
16
  logOut(): Promise<void>;
11
17
  }
12
18
  export { JWT };
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/strategies/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,cAAM,GAAI,SAAQ,SAAS;IACvB,OAAO,CAAC,WAAW,CAAc;gBAErB,OAAO,GAAE,WAAiC;IAMtC,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAItE,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI7E,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAG1C;AAED,OAAO,EAAE,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/strategies/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,cAAM,GAAI,SAAQ,SAAS;IACvB;;OAEG;IACH,OAAO,CAAC,WAAW,CAAc;gBAErB,OAAO,GAAE,WAAiC;IAMtC,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IAK5E,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAKnF,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAI1C;AAED,OAAO,EAAE,GAAG,EAAE,CAAC"}
@@ -1,18 +1,27 @@
1
1
  import { IStrategy } from "./IStrategy";
2
2
  import { verify, sign } from "../functions/jwt";
3
+ /**
4
+ * Basic JWT strategy
5
+ */
3
6
  class JWT extends IStrategy {
7
+ /**
8
+ * Forwarded standard JWT options
9
+ */
4
10
  signOptions;
5
11
  constructor(options = { expiresIn: "1h" }) {
6
12
  super();
7
13
  this.signOptions = options;
8
14
  }
9
15
  serialize(session, globalCfg) {
16
+ // Directly call the sign function, but make it async.
10
17
  return Promise.resolve(sign(session, globalCfg.secret, this.signOptions));
11
18
  }
12
19
  deserialize(token, globalCfg) {
20
+ // The verify function does everything for us, in this case.
13
21
  return verify(token, globalCfg.secret);
14
22
  }
15
23
  logOut() {
24
+ // Since a JWT does not have any data in a DB, there is nothing to do here.
16
25
  return Promise.resolve();
17
26
  }
18
27
  }
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "orange-auth",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Simple modular auth library",
6
- "main": "dist/lib.js",
7
- "types": "dist/lib.d.ts",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
8
11
  "scripts": {
9
12
  "build": "tsc"
10
13
  },
package/.prettierignore DELETED
@@ -1,153 +0,0 @@
1
- # Logs
2
- logs
3
- *.log
4
- npm-debug.log*
5
- yarn-debug.log*
6
- yarn-error.log*
7
- lerna-debug.log*
8
- .pnpm-debug.log*
9
-
10
- # Diagnostic reports (https://nodejs.org/api/report.html)
11
- report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12
-
13
- # Runtime data
14
- pids
15
- *.pid
16
- *.seed
17
- *.pid.lock
18
-
19
- # Directory for instrumented libs generated by jscoverage/JSCover
20
- lib-cov
21
-
22
- # Coverage directory used by tools like istanbul
23
- coverage
24
- *.lcov
25
-
26
- # nyc test coverage
27
- .nyc_output
28
-
29
- # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30
- .grunt
31
-
32
- # Bower dependency directory (https://bower.io/)
33
- bower_components
34
-
35
- # node-waf configuration
36
- .lock-wscript
37
-
38
- # Compiled binary addons (https://nodejs.org/api/addons.html)
39
- build/Release
40
-
41
- # Dependency directories
42
- node_modules/
43
- jspm_packages/
44
-
45
- # Snowpack dependency directory (https://snowpack.dev/)
46
- web_modules/
47
-
48
- # TypeScript cache
49
- *.tsbuildinfo
50
-
51
- # Optional npm cache directory
52
- .npm
53
-
54
- # Optional eslint cache
55
- .eslintcache
56
-
57
- # Optional stylelint cache
58
- .stylelintcache
59
-
60
- # Microbundle cache
61
- .rpt2_cache/
62
- .rts2_cache_cjs/
63
- .rts2_cache_es/
64
- .rts2_cache_umd/
65
-
66
- # Optional REPL history
67
- .node_repl_history
68
-
69
- # Output of 'npm pack'
70
- *.tgz
71
-
72
- # Yarn Integrity file
73
- .yarn-integrity
74
-
75
- # dotenv environment variable files
76
- .env
77
- .env.development.local
78
- .env.test.local
79
- .env.production.local
80
- .env.local
81
-
82
- # parcel-bundler cache (https://parceljs.org/)
83
- .cache
84
- .parcel-cache
85
-
86
- # firebase-admin service-account
87
- firebase
88
-
89
- # Next.js build output
90
- .next
91
- out
92
-
93
- # Nuxt.js build / generate output
94
- .nuxt
95
- dist
96
-
97
- # Gatsby files
98
- .cache/
99
- # Comment in the public line in if your project uses Gatsby and not Next.js
100
- # https://nextjs.org/blog/next-9-1#public-directory-support
101
- # public
102
-
103
- # vuepress build output
104
- .vuepress/dist
105
-
106
- # vuepress v2.x temp and cache directory
107
- .temp
108
-
109
- # Docusaurus cache and generated files
110
- .docusaurus
111
-
112
- # Serverless directories
113
- .serverless/
114
-
115
- # FuseBox cache
116
- .fusebox/
117
-
118
- # DynamoDB Local files
119
- .dynamodb/
120
-
121
- # TernJS port file
122
- .tern-port
123
-
124
- # Stores VSCode versions used for testing VSCode extensions
125
- .vscode-test
126
-
127
- # yarn v2
128
- .yarn/cache
129
- .yarn/unplugged
130
- .yarn/build-state.yml
131
- .yarn/install-state.gz
132
- .pnp.*
133
-
134
- # Cloudflare
135
- .wrangler/
136
-
137
- # Vercel
138
- .vercel/
139
-
140
- # Sentry Vite Plugin
141
- .env.sentry-build-plugin
142
-
143
- # aws-cdk
144
- .cdk.staging
145
- cdk.out
146
-
147
- ## Panda
148
- styled-system
149
- styled-system-studio
150
-
151
- # Shadcn
152
- lib/components/ui/
153
- server/dbClient/
package/.prettierrc DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "printWidth": 120,
3
- "useTabs": false,
4
- "tabWidth": 4,
5
- "semi": true,
6
- "singleQuote": false,
7
- "trailingComma": "all"
8
- }
@@ -1,3 +0,0 @@
1
- declare const _default: import("@typescript-eslint/utils/ts-eslint").FlatConfig.ConfigArray;
2
- export default _default;
3
- //# sourceMappingURL=eslint.config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"eslint.config.d.ts","sourceRoot":"","sources":["eslint.config.ts"],"names":[],"mappings":";AAIA,wBAyGE"}
package/eslint.config.js DELETED
@@ -1,99 +0,0 @@
1
- import eslint from "@eslint/js";
2
- import tseslint from "typescript-eslint";
3
- import prettier from "eslint-plugin-prettier/recommended";
4
- export default tseslint.config({
5
- ignores: [
6
- "dist/*",
7
- "**/*.ts.build-*.mjs",
8
- "*.js",
9
- "*.cjs",
10
- "*.mjs",
11
- ],
12
- }, eslint.configs.recommended, ...tseslint.configs.recommended, {
13
- languageOptions: {
14
- parserOptions: {
15
- warnOnUnsupportedTypeScriptVersion: false,
16
- sourceType: "module",
17
- ecmaVersion: "latest",
18
- },
19
- },
20
- }, {
21
- rules: {
22
- "arrow-spacing": [
23
- "warn",
24
- {
25
- before: true,
26
- after: true,
27
- },
28
- ],
29
- "brace-style": [
30
- "error",
31
- "stroustrup",
32
- {
33
- allowSingleLine: true,
34
- },
35
- ],
36
- "comma-dangle": ["error", "always-multiline"],
37
- "comma-spacing": "error",
38
- "comma-style": "error",
39
- curly: ["error", "multi-line", "consistent"],
40
- "dot-location": ["error", "property"],
41
- "handle-callback-err": "off",
42
- indent: ["error", 4],
43
- "keyword-spacing": "error",
44
- "max-nested-callbacks": [
45
- "error",
46
- {
47
- max: 4,
48
- },
49
- ],
50
- "max-statements-per-line": [
51
- "error",
52
- {
53
- max: 2,
54
- },
55
- ],
56
- "no-console": "off",
57
- "no-empty-function": "error",
58
- "no-floating-decimal": "error",
59
- "no-inline-comments": "error",
60
- "no-lonely-if": "error",
61
- "no-multi-spaces": "error",
62
- "no-multiple-empty-lines": [
63
- "error",
64
- {
65
- max: 2,
66
- maxEOF: 1,
67
- maxBOF: 0,
68
- },
69
- ],
70
- "no-shadow": [
71
- "error",
72
- {
73
- allow: ["err", "resolve", "reject"],
74
- },
75
- ],
76
- "no-trailing-spaces": ["error"],
77
- "no-var": "error",
78
- "object-curly-spacing": ["error", "always"],
79
- "prefer-const": "error",
80
- quotes: ["error", "double"],
81
- semi: ["error", "always"],
82
- "space-before-blocks": "error",
83
- "space-before-function-paren": [
84
- "error",
85
- {
86
- anonymous: "never",
87
- named: "never",
88
- asyncArrow: "always",
89
- },
90
- ],
91
- "space-in-parens": "error",
92
- "space-infix-ops": "error",
93
- "space-unary-ops": "error",
94
- "spaced-comment": "error",
95
- yoda: "error",
96
- "@typescript-eslint/no-misused-promises": "off",
97
- "@typescript-eslint/no-unused-vars": "warn",
98
- },
99
- }, prettier);
package/tsconfig.json DELETED
@@ -1,46 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "incremental": true,
4
-
5
- "target": "es2022",
6
- "lib": ["dom", "dom.iterable", "ES2022"],
7
-
8
- "module": "es2022",
9
- "moduleResolution": "bundler",
10
- "resolveJsonModule": true,
11
-
12
- "checkJs": true,
13
-
14
- "declaration": true,
15
- "declarationMap": true,
16
- "outDir": "dist",
17
- "rootDir": "src",
18
- "removeComments": true,
19
- "importHelpers": true,
20
- "newLine": "lf",
21
-
22
- "verbatimModuleSyntax": true,
23
- "erasableSyntaxOnly": true,
24
- "esModuleInterop": true,
25
- "forceConsistentCasingInFileNames": true,
26
-
27
- "strict": true,
28
- "noImplicitAny": true,
29
- "strictNullChecks": true,
30
- "strictFunctionTypes": true,
31
- "strictPropertyInitialization": true,
32
- "noImplicitThis": true,
33
- "useUnknownInCatchVariables": true,
34
- "alwaysStrict": true,
35
- "noUnusedLocals": true,
36
- "noUnusedParameters": true,
37
- "noImplicitReturns": true,
38
- "noFallthroughCasesInSwitch": true,
39
- "noUncheckedIndexedAccess": true,
40
- "noImplicitOverride": true,
41
- "noPropertyAccessFromIndexSignature": true,
42
-
43
- "skipLibCheck": true
44
- },
45
- "include": ["src/**/*.ts", "eslint.config.ts"]
46
- }