@lobb-js/lobb-ext-auth 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.js +3 -3
- package/extensions/auth/database/init.ts +3 -3
- package/extensions/auth/index.ts +2 -0
- package/extensions/auth/openapi.ts +3 -3
- package/extensions/auth/studio/auth.ts +3 -3
- package/extensions/auth/workflows/actionController.ts +34 -0
- package/extensions/auth/workflows/actions.ts +89 -0
- package/extensions/auth/workflows/baseWorkflow.ts +13 -120
- package/extensions/auth/workflows/index.ts +2 -0
- package/extensions/auth/workflows/sharesWorkflows.ts +10 -9
- package/package.json +3 -3
package/dist/auth.js
CHANGED
|
@@ -17,7 +17,7 @@ export class Auth {
|
|
|
17
17
|
async login(payload) {
|
|
18
18
|
const response = await this.utils.lobb.request({
|
|
19
19
|
method: "POST",
|
|
20
|
-
route: "/api/
|
|
20
|
+
route: "/api/actions/auth_login",
|
|
21
21
|
payload: {
|
|
22
22
|
data: payload,
|
|
23
23
|
},
|
|
@@ -41,8 +41,8 @@ export class Auth {
|
|
|
41
41
|
}
|
|
42
42
|
async logout() {
|
|
43
43
|
await this.utils.lobb.request({
|
|
44
|
-
method: "
|
|
45
|
-
route: "/api/
|
|
44
|
+
method: "POST",
|
|
45
|
+
route: "/api/actions/auth_logout",
|
|
46
46
|
});
|
|
47
47
|
localStorage.removeItem("lobb_session");
|
|
48
48
|
const currentPath = window.location.pathname;
|
|
@@ -12,7 +12,7 @@ async function syncincAdminUserInDB(lobb: Lobb, extensionConfig: ExtensionConfig
|
|
|
12
12
|
// syncinc the admin user in users collection
|
|
13
13
|
const config = extensionConfig;
|
|
14
14
|
const { email, password, ...extraFields } = config.admin;
|
|
15
|
-
const entries = (await lobb.
|
|
15
|
+
const entries = (await lobb.collectionStore.findAll({
|
|
16
16
|
collectionName: "auth_users",
|
|
17
17
|
params: {
|
|
18
18
|
filter: {
|
|
@@ -23,7 +23,7 @@ async function syncincAdminUserInDB(lobb: Lobb, extensionConfig: ExtensionConfig
|
|
|
23
23
|
})).data;
|
|
24
24
|
const adminUser = entries[0];
|
|
25
25
|
if (!adminUser) {
|
|
26
|
-
await lobb.
|
|
26
|
+
await lobb.collectionStore.createOne({
|
|
27
27
|
collectionName: "auth_users",
|
|
28
28
|
data: {
|
|
29
29
|
...extraFields,
|
|
@@ -39,7 +39,7 @@ async function syncincAdminUserInDB(lobb: Lobb, extensionConfig: ExtensionConfig
|
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
if (adminUser.email !== email || !passwordIdentical) {
|
|
42
|
-
await lobb.
|
|
42
|
+
await lobb.collectionStore.updateOne({
|
|
43
43
|
collectionName: "auth_users",
|
|
44
44
|
id: adminUser.id,
|
|
45
45
|
data: {
|
package/extensions/auth/index.ts
CHANGED
|
@@ -5,12 +5,14 @@ import { collections } from "./collections/collections.ts";
|
|
|
5
5
|
import { meta } from "./meta/meta.ts";
|
|
6
6
|
import { migrations } from "./database/migrations.ts";
|
|
7
7
|
import { getWorkflows } from "./workflows/index.ts";
|
|
8
|
+
import { getAuthActions } from "./workflows/actions.ts";
|
|
8
9
|
|
|
9
10
|
export default function auth(extensionConfig: ExtensionConfig): Extension {
|
|
10
11
|
return {
|
|
11
12
|
name: "auth",
|
|
12
13
|
icon: "Key",
|
|
13
14
|
collections: (lobb) => collections(lobb, extensionConfig),
|
|
15
|
+
actions: getAuthActions(extensionConfig),
|
|
14
16
|
migrations: migrations,
|
|
15
17
|
meta: (lobb) => meta(lobb, extensionConfig),
|
|
16
18
|
workflows: getWorkflows(extensionConfig),
|
|
@@ -35,7 +35,7 @@ export const openapi = {
|
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
paths: {
|
|
38
|
-
"/api/
|
|
38
|
+
"/api/actions/auth_login": {
|
|
39
39
|
post: {
|
|
40
40
|
tags: [
|
|
41
41
|
"auth",
|
|
@@ -223,8 +223,8 @@ export const openapi = {
|
|
|
223
223
|
},
|
|
224
224
|
},
|
|
225
225
|
},
|
|
226
|
-
"/api/
|
|
227
|
-
|
|
226
|
+
"/api/actions/auth_logout": {
|
|
227
|
+
post: {
|
|
228
228
|
tags: [
|
|
229
229
|
"auth",
|
|
230
230
|
],
|
|
@@ -26,7 +26,7 @@ export class Auth {
|
|
|
26
26
|
public async login(payload: LoginPayload) {
|
|
27
27
|
const response = await this.utils.lobb.request({
|
|
28
28
|
method: "POST",
|
|
29
|
-
route: "/api/
|
|
29
|
+
route: "/api/actions/auth_login",
|
|
30
30
|
payload: {
|
|
31
31
|
data: payload,
|
|
32
32
|
},
|
|
@@ -55,8 +55,8 @@ export class Auth {
|
|
|
55
55
|
|
|
56
56
|
public async logout() {
|
|
57
57
|
await this.utils.lobb.request({
|
|
58
|
-
method: "
|
|
59
|
-
route: "/api/
|
|
58
|
+
method: "POST",
|
|
59
|
+
route: "/api/actions/auth_logout",
|
|
60
60
|
});
|
|
61
61
|
localStorage.removeItem("lobb_session");
|
|
62
62
|
const currentPath = window.location.pathname;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Workflow } from "@lobb-js/core";
|
|
2
|
+
import type { Context } from "hono";
|
|
3
|
+
import { getBearerToken } from "../utils.ts";
|
|
4
|
+
|
|
5
|
+
// `auth_logout` needs the session token, which arrives as a bearer header. Read
|
|
6
|
+
// it off the Hono context here and pass it to the action (keeping the action
|
|
7
|
+
// pure + internally callable with an explicit token), then return 204.
|
|
8
|
+
//
|
|
9
|
+
// `auth_login` needs no HTTP adaptation — its JSON body { email, password } maps
|
|
10
|
+
// straight to the default action flow.
|
|
11
|
+
|
|
12
|
+
export function getAuthActionControllerWorkflows(): Workflow[] {
|
|
13
|
+
return [
|
|
14
|
+
{
|
|
15
|
+
name: "authLogoutActionController",
|
|
16
|
+
eventName: "core.actions.controller.override",
|
|
17
|
+
handler: async (input, ctx) => {
|
|
18
|
+
if (input.name !== "auth_logout") return;
|
|
19
|
+
|
|
20
|
+
const context = input.context as Context;
|
|
21
|
+
const token = getBearerToken(context);
|
|
22
|
+
if (!token) {
|
|
23
|
+
throw new ctx.LobbError({
|
|
24
|
+
code: "BAD_REQUEST",
|
|
25
|
+
message: "You should pass session's token through the bearer header",
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
await ctx.lobb.runAction("auth_logout", { token });
|
|
30
|
+
return context.body(null, 204);
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { ActionsConfig } from "@lobb-js/core";
|
|
2
|
+
import { LobbError } from "@lobb-js/core";
|
|
3
|
+
import type { ExtensionConfig, User } from "../config/extensionConfigSchema.ts";
|
|
4
|
+
import { generateRandomId } from "../utils.ts";
|
|
5
|
+
import { verify } from "argon2";
|
|
6
|
+
|
|
7
|
+
// Login and logout used to hijack the auth_sessions CRUD endpoints (create =
|
|
8
|
+
// login, deleteMany = logout), which made it impossible to manage session rows
|
|
9
|
+
// normally. They're now first-class actions; the auth_sessions collection is a
|
|
10
|
+
// plain CRUD collection again.
|
|
11
|
+
|
|
12
|
+
export function getAuthActions(_extensionConfig: ExtensionConfig): ActionsConfig {
|
|
13
|
+
return {
|
|
14
|
+
// POST /api/actions/auth_login { data: { email, password } }
|
|
15
|
+
auth_login: {
|
|
16
|
+
handler: async (input: any, ctx) => {
|
|
17
|
+
const email = input.data?.email ?? input.email;
|
|
18
|
+
const password = input.data?.password ?? input.password;
|
|
19
|
+
|
|
20
|
+
const users = await ctx.lobb.collectionStore.findAll({
|
|
21
|
+
collectionName: "auth_users",
|
|
22
|
+
params: { filter: { email } },
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (!users.data.length) {
|
|
26
|
+
throw new LobbError({
|
|
27
|
+
code: "NOT_FOUND",
|
|
28
|
+
message: `The user with this email (${email}) doesnt exist.`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const user = users.data[0] as User;
|
|
33
|
+
|
|
34
|
+
const passwordIsCorrect = await verify(user.password, password);
|
|
35
|
+
if (!passwordIsCorrect) {
|
|
36
|
+
throw new LobbError({
|
|
37
|
+
code: "UNAUTHORIZED",
|
|
38
|
+
message: "The password provided is incorrect. Please verify and try again.",
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const sessionPayload = {
|
|
43
|
+
token: generateRandomId(),
|
|
44
|
+
expires_at: new Date(Date.now() + 3600 * 1000),
|
|
45
|
+
user_id: user.id,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const sessionResult = await ctx.lobb.collectionStore.createOne({
|
|
49
|
+
collectionName: "auth_sessions",
|
|
50
|
+
data: sessionPayload,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
data: {
|
|
55
|
+
access_token: {
|
|
56
|
+
token: sessionPayload.token,
|
|
57
|
+
expires_at: sessionResult.data.expires_at,
|
|
58
|
+
},
|
|
59
|
+
user: {
|
|
60
|
+
id: user.id,
|
|
61
|
+
email: user.email,
|
|
62
|
+
role: user.role,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
// POST /api/actions/auth_logout (bearer header → resolved to { token })
|
|
70
|
+
auth_logout: {
|
|
71
|
+
handler: async (input: any, ctx) => {
|
|
72
|
+
const token = input.token;
|
|
73
|
+
if (!token) {
|
|
74
|
+
throw new LobbError({
|
|
75
|
+
code: "BAD_REQUEST",
|
|
76
|
+
message: "You should pass session's token through the bearer header",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await ctx.lobb.collectionStore.deleteMany({
|
|
81
|
+
collectionName: "auth_sessions",
|
|
82
|
+
filter: { token },
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return { success: true };
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import type { Workflow } from "@lobb-js/core";
|
|
2
2
|
import type { Context } from "hono";
|
|
3
|
-
import type { ExtensionConfig
|
|
4
|
-
import {
|
|
5
|
-
import { verify } from "argon2";
|
|
3
|
+
import type { ExtensionConfig } from "../config/extensionConfigSchema.ts";
|
|
4
|
+
import { getBearerToken } from "../utils.ts";
|
|
6
5
|
|
|
7
6
|
export function getBaseWorkflows(_extensionConfig: ExtensionConfig): Workflow[] {
|
|
8
7
|
return [
|
|
9
8
|
{
|
|
10
9
|
name: "auth_preventAdminUserDeletion",
|
|
11
|
-
eventName: "core.
|
|
10
|
+
eventName: "core.store.preDeleteOne",
|
|
12
11
|
handler: async (input, ctx) => {
|
|
13
|
-
if (input.collectionName !== "auth_users") return;
|
|
12
|
+
if (input.collectionName !== "auth_users") return input;
|
|
13
|
+
if (input.triggeredBy !== "API") return input;
|
|
14
14
|
|
|
15
15
|
if (Number(input.id) === 1) {
|
|
16
16
|
throw new ctx.LobbError({
|
|
@@ -18,13 +18,15 @@ export function getBaseWorkflows(_extensionConfig: ExtensionConfig): Workflow[]
|
|
|
18
18
|
message: "The admin user cannot be deleted.",
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
+
return input;
|
|
21
22
|
},
|
|
22
23
|
},
|
|
23
24
|
{
|
|
24
25
|
name: "auth_preventAdminUserUpdate",
|
|
25
|
-
eventName: "core.
|
|
26
|
+
eventName: "core.store.preUpdateOne",
|
|
26
27
|
handler: async (input, ctx) => {
|
|
27
|
-
if (input.collectionName !== "auth_users") return;
|
|
28
|
+
if (input.collectionName !== "auth_users") return input;
|
|
29
|
+
if (input.triggeredBy !== "API") return input;
|
|
28
30
|
|
|
29
31
|
if (Number(input.id) === 1) {
|
|
30
32
|
throw new ctx.LobbError({
|
|
@@ -32,6 +34,7 @@ export function getBaseWorkflows(_extensionConfig: ExtensionConfig): Workflow[]
|
|
|
32
34
|
message: "The admin user cannot be updated.",
|
|
33
35
|
});
|
|
34
36
|
}
|
|
37
|
+
return input;
|
|
35
38
|
},
|
|
36
39
|
},
|
|
37
40
|
...baseWorkflows,
|
|
@@ -53,7 +56,7 @@ export const baseWorkflows: Workflow[] = [
|
|
|
53
56
|
const context = input.context as Context;
|
|
54
57
|
|
|
55
58
|
// 1) Try the token as a normal user session.
|
|
56
|
-
const sessionsResult = await ctx.workflows.
|
|
59
|
+
const sessionsResult = await ctx.workflows.collectionStore({
|
|
57
60
|
method: "findAll",
|
|
58
61
|
props: {
|
|
59
62
|
collectionName: "auth_sessions",
|
|
@@ -63,7 +66,7 @@ export const baseWorkflows: Workflow[] = [
|
|
|
63
66
|
const session = sessionsResult.data[0];
|
|
64
67
|
|
|
65
68
|
if (session) {
|
|
66
|
-
const usersResult = await ctx.workflows.
|
|
69
|
+
const usersResult = await ctx.workflows.collectionStore({
|
|
67
70
|
method: "findAll",
|
|
68
71
|
props: {
|
|
69
72
|
collectionName: "auth_users",
|
|
@@ -79,7 +82,7 @@ export const baseWorkflows: Workflow[] = [
|
|
|
79
82
|
|
|
80
83
|
// 2) Otherwise try the token as a share. Shares carry their own
|
|
81
84
|
// permissions snapshot and have a fixed expiry — no user identity.
|
|
82
|
-
const sharesResult = await ctx.workflows.
|
|
85
|
+
const sharesResult = await ctx.workflows.collectionStore({
|
|
83
86
|
method: "findAll",
|
|
84
87
|
props: {
|
|
85
88
|
collectionName: "auth_shares",
|
|
@@ -102,114 +105,4 @@ export const baseWorkflows: Workflow[] = [
|
|
|
102
105
|
return input;
|
|
103
106
|
},
|
|
104
107
|
},
|
|
105
|
-
// auth_logins workflows
|
|
106
|
-
{
|
|
107
|
-
name: "auth_userLoginsHandler",
|
|
108
|
-
eventName: "core.controllers.preCreateOne",
|
|
109
|
-
handler: async (input, ctx) => {
|
|
110
|
-
if (input.collectionName === "auth_sessions") {
|
|
111
|
-
const payloadEmail = input.body.data.email;
|
|
112
|
-
const payloadPassword = input.body.data.password;
|
|
113
|
-
|
|
114
|
-
const users = await ctx.workflows.collectionService({
|
|
115
|
-
method: "findAll",
|
|
116
|
-
props: {
|
|
117
|
-
collectionName: "auth_users",
|
|
118
|
-
params: {
|
|
119
|
-
filter: {
|
|
120
|
-
email: payloadEmail,
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
if (!users.data.length) {
|
|
127
|
-
throw new ctx.LobbError({
|
|
128
|
-
code: "NOT_FOUND",
|
|
129
|
-
message: `The user with this email (${payloadEmail}) doesnt exist.`,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const user = users.data[0] as User;
|
|
134
|
-
const hashedPassword = user.password;
|
|
135
|
-
|
|
136
|
-
const passwordIsCorrect = await verify(
|
|
137
|
-
hashedPassword,
|
|
138
|
-
payloadPassword,
|
|
139
|
-
);
|
|
140
|
-
if (!passwordIsCorrect) {
|
|
141
|
-
throw new ctx.LobbError({
|
|
142
|
-
code: "UNAUTHORIZED",
|
|
143
|
-
message:
|
|
144
|
-
"The password provided is incorrect. Please verify and try again.",
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const sessionPayload = {
|
|
149
|
-
token: generateRandomId(),
|
|
150
|
-
expires_at: new Date(Date.now() + 3600 * 1000),
|
|
151
|
-
user_id: user.id,
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const sessionResult = await ctx.workflows.collectionService({
|
|
155
|
-
method: "createOne",
|
|
156
|
-
props: {
|
|
157
|
-
collectionName: "auth_sessions",
|
|
158
|
-
data: sessionPayload,
|
|
159
|
-
},
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
throw new Response(
|
|
163
|
-
JSON.stringify({
|
|
164
|
-
data: {
|
|
165
|
-
access_token: {
|
|
166
|
-
token: sessionPayload.token,
|
|
167
|
-
expires_at: sessionResult.data.expires_at,
|
|
168
|
-
},
|
|
169
|
-
user: {
|
|
170
|
-
id: user.id,
|
|
171
|
-
email: user.email,
|
|
172
|
-
role: user.role,
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
}),
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
name: "auth_userLogoutHandler",
|
|
182
|
-
eventName: "core.controllers.preDeleteMany",
|
|
183
|
-
handler: async (input, ctx) => {
|
|
184
|
-
if (input.collectionName === "auth_sessions") {
|
|
185
|
-
const context = input.context as Context;
|
|
186
|
-
const token = getBearerToken(context);
|
|
187
|
-
|
|
188
|
-
if (!token) {
|
|
189
|
-
throw new ctx.LobbError({
|
|
190
|
-
code: "BAD_REQUEST",
|
|
191
|
-
message:
|
|
192
|
-
"You should pass session's token through the bearer header",
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
await ctx.workflows.collectionService({
|
|
197
|
-
method: "deleteMany",
|
|
198
|
-
props: {
|
|
199
|
-
collectionName: "auth_sessions",
|
|
200
|
-
filter: {
|
|
201
|
-
token: token,
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
throw new Response(
|
|
207
|
-
null,
|
|
208
|
-
{
|
|
209
|
-
status: 204,
|
|
210
|
-
},
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
108
|
];
|
|
@@ -5,6 +5,7 @@ import { meAliasWorkflows } from "./meAliasWorkflows.ts";
|
|
|
5
5
|
import { getCurrentUserPermissionsWorkflow } from "./currentUserPermissionsWorkflow.ts";
|
|
6
6
|
import { getBaseWorkflows } from "./baseWorkflow.ts";
|
|
7
7
|
import { getSharesWorkflows } from "./sharesWorkflows.ts";
|
|
8
|
+
import { getAuthActionControllerWorkflows } from "./actionController.ts";
|
|
8
9
|
import { init } from "../database/init.ts";
|
|
9
10
|
export function getWorkflows(extensionConfig: ExtensionConfig): Workflow[] {
|
|
10
11
|
return [
|
|
@@ -17,6 +18,7 @@ export function getWorkflows(extensionConfig: ExtensionConfig): Workflow[] {
|
|
|
17
18
|
},
|
|
18
19
|
...getBaseWorkflows(extensionConfig),
|
|
19
20
|
...getSharesWorkflows(extensionConfig),
|
|
21
|
+
...getAuthActionControllerWorkflows(),
|
|
20
22
|
|
|
21
23
|
// TODO: think about putting the below workflows above at the beggining
|
|
22
24
|
// this will give us the ability to specify which roles have the ability to login, register etc
|
|
@@ -26,15 +26,16 @@ export function getSharesWorkflows(extensionConfig: ExtensionConfig): Workflow[]
|
|
|
26
26
|
},
|
|
27
27
|
},
|
|
28
28
|
// Normalize the two ways a caller can specify share lifetime into the
|
|
29
|
-
// single `expires_at` column the rest of the system uses.
|
|
30
|
-
//
|
|
31
|
-
// check — so `expires_at` can stay schema-required
|
|
32
|
-
// callers send only `expires_in_seconds`. Keeps an
|
|
33
|
-
// provided" throw for a friendlier error message than the
|
|
34
|
-
// required-field error.
|
|
29
|
+
// single `expires_at` column the rest of the system uses. `order: "pre"`
|
|
30
|
+
// makes it run before the unordered subscribers of preCreateOne — crucially
|
|
31
|
+
// before the required-field check — so `expires_at` can stay schema-required
|
|
32
|
+
// while still letting callers send only `expires_in_seconds`. Keeps an
|
|
33
|
+
// explicit "neither provided" throw for a friendlier error message than the
|
|
34
|
+
// generic required-field error.
|
|
35
35
|
{
|
|
36
36
|
name: "auth_normalizeShareExpiry",
|
|
37
|
-
eventName: "core.
|
|
37
|
+
eventName: "core.store.preCreateOne",
|
|
38
|
+
order: "pre",
|
|
38
39
|
handler: async (input, ctx) => {
|
|
39
40
|
if (input.collectionName !== "auth_shares") return input;
|
|
40
41
|
|
|
@@ -82,7 +83,7 @@ export function getSharesWorkflows(extensionConfig: ExtensionConfig): Workflow[]
|
|
|
82
83
|
// subset of the creator's own permissions. Without this, any user who can
|
|
83
84
|
// create rows in auth_shares could mint a token that grants admin-level
|
|
84
85
|
// access. Only runs for API-triggered creates — internal callers (server
|
|
85
|
-
// code, tests using
|
|
86
|
+
// code, tests using collectionStore directly) are trusted.
|
|
86
87
|
{
|
|
87
88
|
name: "auth_validateShareSubset",
|
|
88
89
|
eventName: "core.store.preCreateOne",
|
|
@@ -125,7 +126,7 @@ export function getSharesWorkflows(extensionConfig: ExtensionConfig): Workflow[]
|
|
|
125
126
|
name: "auth_cleanupExpiredShares",
|
|
126
127
|
eventName: "0 3 * * *",
|
|
127
128
|
handler: async (_input, ctx) => {
|
|
128
|
-
await ctx.lobb.
|
|
129
|
+
await ctx.lobb.collectionStore.deleteMany({
|
|
129
130
|
collectionName: "auth_shares",
|
|
130
131
|
filter: { expires_at: { $lt: new Date().toISOString() } },
|
|
131
132
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobb-js/lobb-ext-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"package": "svelte-package --input extensions/auth/studio"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@lobb-js/core": "^0.
|
|
35
|
+
"@lobb-js/core": "^0.41.0",
|
|
36
36
|
"argon2": "^0.40.3",
|
|
37
37
|
"hono": "^4.7.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@lobb-js/studio": "^0.
|
|
40
|
+
"@lobb-js/studio": "^0.49.0",
|
|
41
41
|
"@lucide/svelte": "^0.563.1",
|
|
42
42
|
"@sveltejs/adapter-node": "^5.5.4",
|
|
43
43
|
"@sveltejs/kit": "^2.60.1",
|