@gauts/auth 0.2.1 → 0.2.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.
- package/README.md +554 -175
- package/dist/adapters/hono/index.d.ts +11 -3
- package/dist/adapters/hono/index.d.ts.map +1 -1
- package/dist/adapters/hono/index.js +28 -10
- package/dist/adapters/hono/index.js.map +1 -1
- package/dist/adapters/prisma/index.d.ts +31 -0
- package/dist/adapters/prisma/index.d.ts.map +1 -0
- package/dist/adapters/prisma/index.js +119 -0
- package/dist/adapters/prisma/index.js.map +1 -0
- package/dist/adapters/redis/index.d.ts +5 -5
- package/dist/adapters/redis/index.d.ts.map +1 -1
- package/dist/adapters/redis/index.js +19 -19
- package/dist/adapters/redis/index.js.map +1 -1
- package/dist/auth.d.ts +4 -4
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +5 -5
- package/dist/auth.js.map +1 -1
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +17 -6
- package/dist/client/index.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -11
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +2 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +7 -5
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/password/index.d.ts.map +1 -1
- package/dist/password/index.js +2 -4
- package/dist/password/index.js.map +1 -1
- package/dist/session/schema.d.ts.map +1 -1
- package/dist/session/schema.js +10 -10
- package/dist/session/schema.js.map +1 -1
- package/dist/session/service.d.ts +4 -4
- package/dist/session/service.d.ts.map +1 -1
- package/dist/session/service.js +91 -85
- package/dist/session/service.js.map +1 -1
- package/dist/session/token.js.map +1 -1
- package/dist/session/types.d.ts +42 -40
- package/dist/session/types.d.ts.map +1 -1
- package/package.json +92 -92
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IACzB,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACvB,SAAS,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,YAAY,CAAC;AAE3D,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,IAAI,GAAG,UAAU,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC7C,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC1B,SAAS,EAAE,UAAU,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,oBAAoB,GAAG;IACxB,SAAS,EAAE,QAAQ,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,sBAAsB,GAAG,oBAAoB,CAAC;AAEnF,MAAM,MAAM,qBAAqB,GAAG;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC5C,CAAC;AA6EF,eAAO,MAAM,qBAAqB,GAAI,SAAQ,cAAmB,KAAG,sBAgFnE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,SAAQ,aAAkB,KAAG,qBAqCjE,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -17,13 +17,9 @@ const SESSION_DEFAULTS = {
|
|
|
17
17
|
max: 10,
|
|
18
18
|
renewInterval: 60 * 60 * 24,
|
|
19
19
|
ttl: 60 * 60 * 24 * 7,
|
|
20
|
-
validation: ["
|
|
20
|
+
validation: ["agent"],
|
|
21
21
|
};
|
|
22
|
-
const SESSION_VALIDATION = new Set([
|
|
23
|
-
"ip",
|
|
24
|
-
"platform",
|
|
25
|
-
"userAgent",
|
|
26
|
-
]);
|
|
22
|
+
const SESSION_VALIDATION = new Set(["agent", "ip", "platform"]);
|
|
27
23
|
const requireInteger = ({ max, min, name, value }) => {
|
|
28
24
|
if (!Number.isInteger(value) || value < min || value > max) {
|
|
29
25
|
throw createError({
|
|
@@ -41,8 +37,7 @@ const resolveSessionValidation = (input) => {
|
|
|
41
37
|
});
|
|
42
38
|
}
|
|
43
39
|
const fields = input;
|
|
44
|
-
if (fields.some((field) => typeof field !== "string" ||
|
|
45
|
-
!SESSION_VALIDATION.has(field))) {
|
|
40
|
+
if (fields.some((field) => typeof field !== "string" || !SESSION_VALIDATION.has(field))) {
|
|
46
41
|
throw createError({
|
|
47
42
|
code: "AUTH_CONFIG_INVALID",
|
|
48
43
|
message: "session.validation contains an invalid field.",
|
|
@@ -65,9 +60,7 @@ export const resolvePasswordConfig = (config = {}) => {
|
|
|
65
60
|
});
|
|
66
61
|
}
|
|
67
62
|
const algorithm = config.algorithm;
|
|
68
|
-
if (algorithm !== undefined &&
|
|
69
|
-
algorithm !== "argon2id" &&
|
|
70
|
-
algorithm !== "bcrypt") {
|
|
63
|
+
if (algorithm !== undefined && algorithm !== "argon2id" && algorithm !== "bcrypt") {
|
|
71
64
|
throw createError({
|
|
72
65
|
code: "AUTH_CONFIG_INVALID",
|
|
73
66
|
message: "Password algorithm is invalid.",
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type AuthErrorCode = "AUTH_CONFIG_INVALID" | "PASSWORD_INPUT_INVALID" | "SESSION_CLIENT_MISMATCH" | "SESSION_DATA_INVALID" | "SESSION_INVALID" | "SESSION_LIMIT_REACHED" | "SESSION_NOT_FOUND" | "
|
|
1
|
+
export type AuthErrorCode = "AUTH_CONFIG_INVALID" | "PASSWORD_INPUT_INVALID" | "SESSION_CLIENT_MISMATCH" | "SESSION_DATA_INVALID" | "SESSION_INVALID" | "SESSION_LIMIT_REACHED" | "SESSION_NOT_FOUND" | "DB_UNAVAILABLE" | "REDIS_UNAVAILABLE";
|
|
2
2
|
export type AuthError = Error & {
|
|
3
3
|
code: AuthErrorCode;
|
|
4
4
|
};
|
|
@@ -7,6 +7,6 @@ export type AuthErrorInput = {
|
|
|
7
7
|
code: AuthErrorCode;
|
|
8
8
|
message: string;
|
|
9
9
|
};
|
|
10
|
-
export declare const createError: ({ cause, code, message
|
|
10
|
+
export declare const createError: ({ cause, code, message }: AuthErrorInput) => AuthError;
|
|
11
11
|
export declare const isAuthError: (error: unknown) => error is AuthError;
|
|
12
12
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACnB,qBAAqB,GACrB,wBAAwB,GACxB,yBAAyB,GACzB,sBAAsB,GACtB,iBAAiB,GACjB,uBAAuB,GACvB,mBAAmB,GACnB,gBAAgB,GAChB,mBAAmB,CAAC;AAE1B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG;IAC5B,IAAI,EAAE,aAAa,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,0BAA0B,cAAc,KAAG,SAOtE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,SAOrD,CAAC"}
|
package/dist/errors.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
export const createError = ({ cause, code, message
|
|
1
|
+
export const createError = ({ cause, code, message }) => {
|
|
2
2
|
const error = new Error(message, cause === undefined ? undefined : { cause });
|
|
3
3
|
error.name = "AuthError";
|
|
4
4
|
error.code = code;
|
|
5
5
|
return error;
|
|
6
6
|
};
|
|
7
|
-
export const isAuthError = (error) =>
|
|
8
|
-
error
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export const isAuthError = (error) => {
|
|
8
|
+
return (error instanceof Error &&
|
|
9
|
+
error.name === "AuthError" &&
|
|
10
|
+
"code" in error &&
|
|
11
|
+
typeof error.code === "string");
|
|
12
|
+
};
|
|
11
13
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAqBA,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAqBA,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAkB,EAAa,EAAE;IAC/E,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAc,CAAC;IAE3F,KAAK,CAAC,IAAI,GAAG,WAAW,CAAC;IACzB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IAElB,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAc,EAAsB,EAAE;IAC9D,OAAO,CACH,KAAK,YAAY,KAAK;QACtB,KAAK,CAAC,IAAI,KAAK,WAAW;QAC1B,MAAM,IAAI,KAAK;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CACjC,CAAC;AACN,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export type { BcryptConfig, Argon2idConfig, PasswordConfig, SessionConfig, Sessi
|
|
|
4
4
|
export { isAuthError } from "./errors.js";
|
|
5
5
|
export type { AuthError, AuthErrorCode } from "./errors.js";
|
|
6
6
|
export type { PasswordService } from "./password/index.js";
|
|
7
|
-
export type { ActiveSession, CreateSessionRecord, CreatedSession,
|
|
7
|
+
export type { ActiveSession, CreateSessionRecord, CreatedSession, DbAdapter, RedisAdapter, ResolvedSession, Session, SessionInput, SessionRecord, SessionService, } from "./session/types.js";
|
|
8
8
|
export type { SessionClient, SessionClientInput } from "./client/index.js";
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC5D,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC5D,YAAY,EACR,YAAY,EACZ,cAAc,EACd,cAAc,EACd,aAAa,EACb,iBAAiB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,YAAY,EACR,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,SAAS,EACT,YAAY,EACZ,eAAe,EACf,OAAO,EACP,YAAY,EACZ,aAAa,EACb,cAAc,GACjB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/password/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/password/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAG3D,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,EAAE,UAAU,GAAG,QAAQ,CAAC;IACjC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7E,CAAC;AAqEF,eAAO,MAAM,cAAc,GAAI,QAAQ,sBAAsB,KAAG,eAE/D,CAAC"}
|
package/dist/password/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as argon2 from "argon2";
|
|
|
2
2
|
import { compare as compareBcrypt, hash as hashBcrypt } from "bcryptjs";
|
|
3
3
|
import { createError } from "../errors.js";
|
|
4
4
|
const BCRYPT_PATTERN = /^\$2[aby]\$\d{2}\$[./A-Za-z0-9]{53}$/;
|
|
5
|
-
const requirePassword = ({ password, maxBytes
|
|
5
|
+
const requirePassword = ({ password, maxBytes }) => {
|
|
6
6
|
const bytes = Buffer.byteLength(password, "utf8");
|
|
7
7
|
if (bytes < 1 || bytes > maxBytes) {
|
|
8
8
|
throw createError({
|
|
@@ -46,8 +46,6 @@ const createBcrypt = (config) => ({
|
|
|
46
46
|
},
|
|
47
47
|
});
|
|
48
48
|
export const createPassword = (config) => {
|
|
49
|
-
return config.algorithm === "bcrypt"
|
|
50
|
-
? createBcrypt(config)
|
|
51
|
-
: createArgon2id(config);
|
|
49
|
+
return config.algorithm === "bcrypt" ? createBcrypt(config) : createArgon2id(config);
|
|
52
50
|
};
|
|
53
51
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/password/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/password/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,UAAU,CAAC;AAExE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAa3C,MAAM,cAAc,GAAG,sCAAsC,CAAC;AAE9D,MAAM,eAAe,GAAG,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAwB,EAAE,EAAE;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAElD,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;QAChC,MAAM,WAAW,CAAC;YACd,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EAAE,uCAAuC,MAAM,CAAC,QAAQ,CAAC,SAAS;SAC5E,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACnB,MAAkE,EACnD,EAAE,CAAC,CAAC;IACnB,SAAS,EAAE,UAAU;IAErB,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QACrB,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEzD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;YACzB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,IAAI,EAAE,MAAM,CAAC,QAAQ;SACxB,CAAC,CAAC;IACP,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;QACvC,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEzD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,CACjB,MAAgE,EACjD,EAAE,CAAC,CAAC;IACnB,SAAS,EAAE,QAAQ;IAEnB,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QACrB,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACzD,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;QACvC,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE/D,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAA8B,EAAmB,EAAE;IAC9E,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AACzF,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/session/schema.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAsBzD,eAAO,MAAM,aAAa,GAAI,KAAK,SAAS,MAAM,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/session/schema.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAsBzD,eAAO,MAAM,aAAa,GAAI,KAAK,SAAS,MAAM,EAAE,SAAS,aAAa,CAAC,KAAK,CAAC,KAAG,MAUnF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,KAAK,SAAS,MAAM,EAAE,KAAK,MAAM,KAAG,aAAa,CAAC,KAAK,CAAC,GAAG,IAuBvF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,KAAK,SAAS,MAAM,EAAE,QAAQ,aAAa,CAAC,KAAK,CAAC,KAAG,OAAO,CAAC,KAAK,CAQ1F,CAAC"}
|
package/dist/session/schema.js
CHANGED
|
@@ -8,9 +8,9 @@ const isDateString = (value) => {
|
|
|
8
8
|
};
|
|
9
9
|
const isClient = (value) => {
|
|
10
10
|
return (isRecord(value) &&
|
|
11
|
+
isNullableString(value.agent) &&
|
|
11
12
|
isNullableString(value.ip) &&
|
|
12
|
-
isNullableString(value.platform)
|
|
13
|
-
isNullableString(value.userAgent));
|
|
13
|
+
isNullableString(value.platform));
|
|
14
14
|
};
|
|
15
15
|
export const encodeSession = (session) => {
|
|
16
16
|
try {
|
|
@@ -34,23 +34,23 @@ export const parseSession = (raw) => {
|
|
|
34
34
|
}
|
|
35
35
|
if (!isRecord(value) ||
|
|
36
36
|
typeof value.id !== "string" ||
|
|
37
|
-
typeof value.
|
|
37
|
+
typeof value.account_id !== "string" ||
|
|
38
38
|
!isRecord(value.data) ||
|
|
39
39
|
!isClient(value.client) ||
|
|
40
|
-
!isDateString(value.
|
|
41
|
-
!isDateString(value.
|
|
42
|
-
!isDateString(value.
|
|
40
|
+
!isDateString(value.created_at) ||
|
|
41
|
+
!isDateString(value.touched_at) ||
|
|
42
|
+
!isDateString(value.expires_at)) {
|
|
43
43
|
return null;
|
|
44
44
|
}
|
|
45
45
|
return value;
|
|
46
46
|
};
|
|
47
47
|
export const toSession = (stored) => ({
|
|
48
|
-
|
|
48
|
+
account_id: stored.account_id,
|
|
49
49
|
client: stored.client,
|
|
50
|
-
|
|
50
|
+
created_at: new Date(stored.created_at),
|
|
51
51
|
data: stored.data,
|
|
52
|
-
|
|
52
|
+
expires_at: new Date(stored.expires_at),
|
|
53
53
|
id: stored.id,
|
|
54
|
-
|
|
54
|
+
touched_at: new Date(stored.touched_at),
|
|
55
55
|
});
|
|
56
56
|
//# sourceMappingURL=schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/session/schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/session/schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAClE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEzE,MAAM,gBAAgB,GAAG,CAAC,KAAc,EAA0B,EAAE;IAChE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,KAAc,EAAmB,EAAE;IACrD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,KAAc,EAA0B,EAAE;IACxD,OAAO,CACH,QAAQ,CAAC,KAAK,CAAC;QACf,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC;QAC7B,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CACnC,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAuB,OAA6B,EAAU,EAAE;IACzF,IAAI,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,WAAW,CAAC;YACd,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,sBAAsB;YAC5B,OAAO,EAAE,yCAAyC;SACrD,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAuB,GAAW,EAA+B,EAAE;IAC3F,IAAI,KAAc,CAAC;IAEnB,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IACI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAChB,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC5B,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;QACrB,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;QACvB,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC;QAC/B,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC;QAC/B,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,EACjC,CAAC;QACC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,KAA6B,CAAC;AACzC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAuB,MAA4B,EAAkB,EAAE,CAAC,CAAC;IAC9F,UAAU,EAAE,MAAM,CAAC,UAAU;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,UAAU,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,UAAU,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;IACvC,EAAE,EAAE,MAAM,CAAC,EAAE;IACb,UAAU,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;CAC1C,CAAC,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ResolvedSessionConfig } from "../config.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { DbAdapter, RedisAdapter, SessionService } from "./types.js";
|
|
3
3
|
type SessionDeps = {
|
|
4
4
|
config: ResolvedSessionConfig;
|
|
5
|
+
db: DbAdapter;
|
|
5
6
|
now?: () => Date;
|
|
6
|
-
|
|
7
|
-
redis: RedisSessionStore;
|
|
7
|
+
redis: RedisAdapter;
|
|
8
8
|
};
|
|
9
|
-
export declare const createSessionService: <TData extends object>({ config,
|
|
9
|
+
export declare const createSessionService: <TData extends object>({ config, db, now, redis, }: SessionDeps) => SessionService<TData>;
|
|
10
10
|
export {};
|
|
11
11
|
//# sourceMappingURL=service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/session/service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAI1D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/session/service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAI1D,OAAO,KAAK,EAER,SAAS,EACT,YAAY,EAGZ,cAAc,EAEjB,MAAM,YAAY,CAAC;AAEpB,KAAK,WAAW,GAAG;IACf,MAAM,EAAE,qBAAqB,CAAC;IAC9B,EAAE,EAAE,SAAS,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;CACvB,CAAC;AAyBF,eAAO,MAAM,oBAAoB,GAAI,KAAK,SAAS,MAAM,EAAE,6BAKxD,WAAW,KAAG,cAAc,CAAC,KAAK,CA4UpC,CAAC"}
|
package/dist/session/service.js
CHANGED
|
@@ -4,15 +4,17 @@ import { createError, isAuthError } from "../errors.js";
|
|
|
4
4
|
import { encodeSession, parseSession, toSession } from "./schema.js";
|
|
5
5
|
import { createToken, hashToken, tokenPattern } from "./token.js";
|
|
6
6
|
const toActiveSession = (session) => ({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
account_id: session.account_id,
|
|
8
|
+
agent: session.agent,
|
|
9
|
+
created_at: session.created_at,
|
|
10
|
+
expires_at: session.expires_at,
|
|
11
11
|
id: session.id,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
ip: session.ip,
|
|
13
|
+
platform: session.platform,
|
|
14
|
+
revoked_at: session.revoked_at,
|
|
15
|
+
updated_at: session.updated_at,
|
|
14
16
|
});
|
|
15
|
-
export const createSessionService = ({ config, now = () => new Date(),
|
|
17
|
+
export const createSessionService = ({ config, db, now = () => new Date(), redis, }) => {
|
|
16
18
|
const runRedis = async (operation) => {
|
|
17
19
|
try {
|
|
18
20
|
return await operation();
|
|
@@ -28,7 +30,7 @@ export const createSessionService = ({ config, now = () => new Date(), records,
|
|
|
28
30
|
});
|
|
29
31
|
}
|
|
30
32
|
};
|
|
31
|
-
const
|
|
33
|
+
const runDb = async (operation) => {
|
|
32
34
|
try {
|
|
33
35
|
return await operation();
|
|
34
36
|
}
|
|
@@ -38,19 +40,19 @@ export const createSessionService = ({ config, now = () => new Date(), records,
|
|
|
38
40
|
}
|
|
39
41
|
throw createError({
|
|
40
42
|
cause: error,
|
|
41
|
-
code: "
|
|
42
|
-
message: "Session
|
|
43
|
+
code: "DB_UNAVAILABLE",
|
|
44
|
+
message: "Session database unavailable.",
|
|
43
45
|
});
|
|
44
46
|
}
|
|
45
47
|
};
|
|
46
|
-
const getActive = async (
|
|
48
|
+
const getActive = async (account_id) => {
|
|
47
49
|
const current = now();
|
|
48
|
-
const rows = await
|
|
49
|
-
const valid = rows.filter((row) => row.
|
|
50
|
+
const rows = await runDb(() => db.findActive({ account_id, now: current }));
|
|
51
|
+
const valid = rows.filter((row) => row.revoked_at === null && row.expires_at.getTime() > current.getTime());
|
|
50
52
|
if (valid.length === 0) {
|
|
51
53
|
return [];
|
|
52
54
|
}
|
|
53
|
-
const active = await runRedis(() => redis.exists(valid.map((row) => row.
|
|
55
|
+
const active = await runRedis(() => redis.exists(valid.map((row) => row.token_hash)));
|
|
54
56
|
if (active.length !== valid.length) {
|
|
55
57
|
throw createError({
|
|
56
58
|
code: "REDIS_UNAVAILABLE",
|
|
@@ -59,43 +61,44 @@ export const createSessionService = ({ config, now = () => new Date(), records,
|
|
|
59
61
|
}
|
|
60
62
|
return valid.filter((_, index) => active[index]);
|
|
61
63
|
};
|
|
62
|
-
const revokeRows = async ({
|
|
64
|
+
const revokeRows = async ({ revoked_at, rows }) => {
|
|
63
65
|
if (rows.length === 0) {
|
|
64
66
|
return [];
|
|
65
67
|
}
|
|
66
|
-
await runRedis(() => redis.delete(rows.map((row) => row.
|
|
67
|
-
const
|
|
68
|
-
await
|
|
69
|
-
return
|
|
68
|
+
await runRedis(() => redis.delete(rows.map((row) => row.token_hash)));
|
|
69
|
+
const session_ids = rows.map((row) => row.id);
|
|
70
|
+
await runDb(() => db.revoke({ revoked_at, session_ids }));
|
|
71
|
+
return session_ids;
|
|
70
72
|
};
|
|
71
73
|
const validateSession = async (input) => {
|
|
72
74
|
if (!tokenPattern.test(input.token)) {
|
|
73
75
|
return null;
|
|
74
76
|
}
|
|
75
|
-
const
|
|
76
|
-
const raw = await runRedis(() => redis.get(
|
|
77
|
+
const token_hash = hashToken(input.token);
|
|
78
|
+
const raw = await runRedis(() => redis.get(token_hash));
|
|
77
79
|
if (!raw) {
|
|
78
80
|
return null;
|
|
79
81
|
}
|
|
80
82
|
const stored = parseSession(raw);
|
|
81
83
|
if (!stored) {
|
|
82
|
-
await runRedis(() => redis.delete([
|
|
84
|
+
await runRedis(() => redis.delete([token_hash]));
|
|
83
85
|
return null;
|
|
84
86
|
}
|
|
85
87
|
const current = now();
|
|
86
|
-
if (Date.parse(stored.
|
|
87
|
-
await runRedis(() => redis.delete([
|
|
88
|
+
if (Date.parse(stored.expires_at) <= current.getTime()) {
|
|
89
|
+
await runRedis(() => redis.delete([token_hash]));
|
|
88
90
|
return null;
|
|
89
91
|
}
|
|
90
92
|
const client = normalizeClient(input.client);
|
|
91
|
-
|
|
93
|
+
const matches = matchesClient({
|
|
92
94
|
current: client,
|
|
93
95
|
stored: stored.client,
|
|
94
96
|
validation: config.validation,
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
+
});
|
|
98
|
+
if (!matches) {
|
|
99
|
+
await runRedis(() => redis.delete([token_hash]));
|
|
97
100
|
try {
|
|
98
|
-
await
|
|
101
|
+
await runDb(() => db.revoke({ revoked_at: current, session_ids: [stored.id] }));
|
|
99
102
|
}
|
|
100
103
|
catch (error) {
|
|
101
104
|
throw createError({
|
|
@@ -109,59 +112,61 @@ export const createSessionService = ({ config, now = () => new Date(), records,
|
|
|
109
112
|
message: "Session client identity changed and the session was revoked.",
|
|
110
113
|
});
|
|
111
114
|
}
|
|
112
|
-
return { current, stored,
|
|
115
|
+
return { current, stored, token_hash };
|
|
113
116
|
};
|
|
114
117
|
return {
|
|
115
118
|
create: async (input) => {
|
|
116
|
-
if (!input.
|
|
119
|
+
if (!input.account_id) {
|
|
117
120
|
throw createError({
|
|
118
121
|
code: "SESSION_DATA_INVALID",
|
|
119
122
|
message: "Session account ID is required.",
|
|
120
123
|
});
|
|
121
124
|
}
|
|
122
125
|
const client = normalizeClient(input.client);
|
|
123
|
-
const
|
|
124
|
-
const
|
|
126
|
+
const created_at = now();
|
|
127
|
+
const expires_at = new Date(created_at.getTime() + config.ttl * 1000);
|
|
125
128
|
const token = createToken();
|
|
126
|
-
const
|
|
129
|
+
const token_hash = hashToken(token);
|
|
127
130
|
const id = randomUUID();
|
|
128
131
|
const stored = {
|
|
129
|
-
|
|
132
|
+
account_id: input.account_id,
|
|
130
133
|
client,
|
|
131
|
-
|
|
134
|
+
created_at: created_at.toISOString(),
|
|
132
135
|
data: input.data,
|
|
133
|
-
|
|
136
|
+
expires_at: expires_at.toISOString(),
|
|
134
137
|
id,
|
|
135
|
-
|
|
138
|
+
touched_at: created_at.toISOString(),
|
|
136
139
|
};
|
|
137
140
|
const value = encodeSession(stored);
|
|
138
|
-
const active = await getActive(input.
|
|
141
|
+
const active = await getActive(input.account_id);
|
|
139
142
|
if (active.length >= config.max) {
|
|
140
143
|
throw createError({
|
|
141
144
|
code: "SESSION_LIMIT_REACHED",
|
|
142
145
|
message: `Maximum active sessions reached (${String(config.max)}).`,
|
|
143
146
|
});
|
|
144
147
|
}
|
|
145
|
-
await
|
|
146
|
-
|
|
147
|
-
client,
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
await runDb(() => db.create({
|
|
149
|
+
account_id: input.account_id,
|
|
150
|
+
agent: client.agent,
|
|
151
|
+
created_at,
|
|
152
|
+
expires_at,
|
|
150
153
|
id,
|
|
151
|
-
|
|
154
|
+
ip: client.ip,
|
|
155
|
+
platform: client.platform,
|
|
156
|
+
token_hash,
|
|
152
157
|
}));
|
|
153
158
|
try {
|
|
154
|
-
await runRedis(() => redis.create({
|
|
159
|
+
await runRedis(() => redis.create({ token_hash, ttl: config.ttl, value }));
|
|
155
160
|
}
|
|
156
161
|
catch (error) {
|
|
157
162
|
try {
|
|
158
|
-
await
|
|
163
|
+
await runDb(() => db.revoke({ revoked_at: now(), session_ids: [id] }));
|
|
159
164
|
}
|
|
160
|
-
catch (
|
|
165
|
+
catch (dbError) {
|
|
161
166
|
throw createError({
|
|
162
|
-
cause: new AggregateError([error,
|
|
163
|
-
code: "
|
|
164
|
-
message: "Session creation
|
|
167
|
+
cause: new AggregateError([error, dbError]),
|
|
168
|
+
code: "DB_UNAVAILABLE",
|
|
169
|
+
message: "Session creation compensation failed.",
|
|
165
170
|
});
|
|
166
171
|
}
|
|
167
172
|
throw error;
|
|
@@ -176,25 +181,24 @@ export const createSessionService = ({ config, now = () => new Date(), records,
|
|
|
176
181
|
if (!validated) {
|
|
177
182
|
return null;
|
|
178
183
|
}
|
|
179
|
-
const { current, stored,
|
|
180
|
-
const due = current.getTime() - Date.parse(stored.
|
|
181
|
-
config.renewInterval * 1000;
|
|
184
|
+
const { current, stored, token_hash } = validated;
|
|
185
|
+
const due = current.getTime() - Date.parse(stored.touched_at) >= config.renewInterval * 1000;
|
|
182
186
|
if (!due) {
|
|
183
187
|
return { renewed: false, session: toSession(stored) };
|
|
184
188
|
}
|
|
185
|
-
const
|
|
189
|
+
const expires_at = new Date(current.getTime() + config.ttl * 1000);
|
|
186
190
|
const renewed = {
|
|
187
191
|
...stored,
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
expires_at: expires_at.toISOString(),
|
|
193
|
+
touched_at: current.toISOString(),
|
|
190
194
|
};
|
|
191
|
-
await
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
await runDb(() => db.updateExpiry({
|
|
196
|
+
expires_at,
|
|
197
|
+
session_id: stored.id,
|
|
198
|
+
updated_at: current,
|
|
195
199
|
}));
|
|
196
200
|
const updated = await runRedis(() => redis.update({
|
|
197
|
-
|
|
201
|
+
token_hash,
|
|
198
202
|
ttl: config.ttl,
|
|
199
203
|
value: encodeSession(renewed),
|
|
200
204
|
}));
|
|
@@ -208,62 +212,64 @@ export const createSessionService = ({ config, now = () => new Date(), records,
|
|
|
208
212
|
if (!tokenPattern.test(token)) {
|
|
209
213
|
return [];
|
|
210
214
|
}
|
|
211
|
-
const
|
|
212
|
-
const raw = await runRedis(() => redis.get(
|
|
215
|
+
const token_hash = hashToken(token);
|
|
216
|
+
const raw = await runRedis(() => redis.get(token_hash));
|
|
213
217
|
if (!raw) {
|
|
214
218
|
return [];
|
|
215
219
|
}
|
|
216
220
|
const stored = parseSession(raw);
|
|
217
|
-
await runRedis(() => redis.delete([
|
|
221
|
+
await runRedis(() => redis.delete([token_hash]));
|
|
218
222
|
if (!stored) {
|
|
219
223
|
return [];
|
|
220
224
|
}
|
|
221
|
-
await
|
|
225
|
+
await runDb(() => db.revoke({ revoked_at: now(), session_ids: [stored.id] }));
|
|
222
226
|
return [stored.id];
|
|
223
227
|
},
|
|
224
|
-
revoke: async ({
|
|
225
|
-
const row = await
|
|
226
|
-
if (row?.
|
|
228
|
+
revoke: async ({ account_id, session_id }) => {
|
|
229
|
+
const row = await runDb(() => db.find({ account_id, session_id }));
|
|
230
|
+
if (row?.revoked_at !== null) {
|
|
227
231
|
throw createError({
|
|
228
232
|
code: "SESSION_NOT_FOUND",
|
|
229
233
|
message: "Session not found.",
|
|
230
234
|
});
|
|
231
235
|
}
|
|
232
|
-
return revokeRows({
|
|
236
|
+
return revokeRows({ revoked_at: now(), rows: [row] });
|
|
233
237
|
},
|
|
234
|
-
revokeAccount: async (
|
|
235
|
-
return revokeRows({
|
|
238
|
+
revokeAccount: async (account_id) => {
|
|
239
|
+
return revokeRows({
|
|
240
|
+
revoked_at: now(),
|
|
241
|
+
rows: await getActive(account_id),
|
|
242
|
+
});
|
|
236
243
|
},
|
|
237
|
-
list: async (
|
|
238
|
-
return (await getActive(
|
|
244
|
+
list: async (account_id) => {
|
|
245
|
+
return (await getActive(account_id)).map(toActiveSession);
|
|
239
246
|
},
|
|
240
|
-
sync: async ({
|
|
241
|
-
const rows = await getActive(
|
|
247
|
+
sync: async ({ account_id, data }) => {
|
|
248
|
+
const rows = await getActive(account_id);
|
|
242
249
|
if (rows.length === 0) {
|
|
243
250
|
return;
|
|
244
251
|
}
|
|
245
|
-
const
|
|
246
|
-
const values = await runRedis(() => redis.getMany(
|
|
247
|
-
if (values.length !==
|
|
252
|
+
const token_hashes = rows.map((row) => row.token_hash);
|
|
253
|
+
const values = await runRedis(() => redis.getMany(token_hashes));
|
|
254
|
+
if (values.length !== token_hashes.length) {
|
|
248
255
|
throw createError({
|
|
249
256
|
code: "REDIS_UNAVAILABLE",
|
|
250
257
|
message: "Authentication service returned invalid data.",
|
|
251
258
|
});
|
|
252
259
|
}
|
|
253
260
|
await Promise.all(values.map(async (raw, index) => {
|
|
254
|
-
if (!raw)
|
|
261
|
+
if (!raw)
|
|
255
262
|
return;
|
|
256
|
-
}
|
|
257
263
|
const stored = parseSession(raw);
|
|
258
|
-
const
|
|
259
|
-
if (!stored || !
|
|
260
|
-
if (
|
|
261
|
-
await runRedis(() => redis.delete([
|
|
264
|
+
const token_hash = token_hashes[index];
|
|
265
|
+
if (!stored || !token_hash || stored.account_id !== account_id) {
|
|
266
|
+
if (token_hash) {
|
|
267
|
+
await runRedis(() => redis.delete([token_hash]));
|
|
262
268
|
}
|
|
263
269
|
return;
|
|
264
270
|
}
|
|
265
271
|
await runRedis(() => redis.keep({
|
|
266
|
-
|
|
272
|
+
token_hash,
|
|
267
273
|
value: encodeSession({ ...stored, data }),
|
|
268
274
|
}));
|
|
269
275
|
}));
|