@kevisual/kv-login 0.1.3 → 0.1.4

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/app.js CHANGED
@@ -2052,7 +2052,7 @@ var require_browser = __commonJS((exports) => {
2052
2052
  });
2053
2053
  });
2054
2054
 
2055
- // ../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/development/lit-html.js
2055
+ // ../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/development/lit-html.js
2056
2056
  var DEV_MODE = true;
2057
2057
  var ENABLE_EXTRA_SECURITY_HOOKS = true;
2058
2058
  var ENABLE_SHADYDOM_NOPATCH = true;
@@ -2857,7 +2857,7 @@ class ElementPart {
2857
2857
  }
2858
2858
  var polyfillSupport = DEV_MODE ? global.litHtmlPolyfillSupportDevMode : global.litHtmlPolyfillSupport;
2859
2859
  polyfillSupport?.(Template, ChildPart);
2860
- (global.litHtmlVersions ??= []).push("3.3.1");
2860
+ (global.litHtmlVersions ??= []).push("3.3.2");
2861
2861
  if (DEV_MODE && global.litHtmlVersions.length > 1) {
2862
2862
  queueMicrotask(() => {
2863
2863
  issueWarning("multiple-versions", `Multiple versions of Lit loaded. ` + `Loading multiple versions is not recommended.`);
@@ -2901,7 +2901,7 @@ if (ENABLE_EXTRA_SECURITY_HOOKS) {
2901
2901
  }
2902
2902
  }
2903
2903
 
2904
- // ../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/development/directive.js
2904
+ // ../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/development/directive.js
2905
2905
  var PartType = {
2906
2906
  ATTRIBUTE: 1,
2907
2907
  CHILD: 2,
@@ -2933,7 +2933,7 @@ class Directive {
2933
2933
  }
2934
2934
  }
2935
2935
 
2936
- // ../../node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/development/directives/unsafe-html.js
2936
+ // ../../node_modules/.pnpm/lit-html@3.3.2/node_modules/lit-html/development/directives/unsafe-html.js
2937
2937
  var HTML_RESULT2 = 1;
2938
2938
 
2939
2939
  class UnsafeHTMLDirective extends Directive {
@@ -4166,6 +4166,894 @@ class EventEmitter {
4166
4166
  var eventEmitter = new EventEmitter;
4167
4167
  var emit = (event) => eventEmitter.emit(event);
4168
4168
 
4169
+ // ../../node_modules/.pnpm/@kevisual+api@0.0.8/node_modules/@kevisual/api/query/query-login/login-cache.ts
4170
+ class LoginCacheStore2 {
4171
+ cache;
4172
+ name;
4173
+ cacheData;
4174
+ constructor(opts) {
4175
+ if (!opts.cache) {
4176
+ throw new Error("cache is required");
4177
+ }
4178
+ this.cache = opts.cache;
4179
+ this.cacheData = {
4180
+ loginUsers: [],
4181
+ user: undefined,
4182
+ id: undefined,
4183
+ accessToken: undefined,
4184
+ refreshToken: undefined
4185
+ };
4186
+ this.name = opts.name;
4187
+ }
4188
+ async setValue(value) {
4189
+ await this.cache.set(this.name, value);
4190
+ this.cacheData = value;
4191
+ return value;
4192
+ }
4193
+ async delValue() {
4194
+ await this.cache.del();
4195
+ }
4196
+ getValue() {
4197
+ return this.cache.get(this.name);
4198
+ }
4199
+ async init() {
4200
+ const defaultData = {
4201
+ loginUsers: [],
4202
+ user: null,
4203
+ id: null,
4204
+ accessToken: null,
4205
+ refreshToken: null
4206
+ };
4207
+ if (this.cache.init) {
4208
+ try {
4209
+ const cacheData = await this.cache.init();
4210
+ this.cacheData = cacheData || defaultData;
4211
+ } catch (error) {
4212
+ console.log("cacheInit error", error);
4213
+ }
4214
+ } else {
4215
+ this.cacheData = await this.getValue() || defaultData;
4216
+ }
4217
+ }
4218
+ async setLoginUser(user) {
4219
+ const has = this.cacheData.loginUsers.find((u) => u.id === user.id);
4220
+ if (has) {
4221
+ this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id);
4222
+ }
4223
+ this.cacheData.loginUsers.push(user);
4224
+ this.cacheData.user = user.user;
4225
+ this.cacheData.id = user.id;
4226
+ this.cacheData.accessToken = user.accessToken;
4227
+ this.cacheData.refreshToken = user.refreshToken;
4228
+ await this.setValue(this.cacheData);
4229
+ }
4230
+ getCurrentUser() {
4231
+ const cacheData = this.cacheData;
4232
+ return Promise.resolve(cacheData.user);
4233
+ }
4234
+ getCurrentUserList() {
4235
+ return Promise.resolve(this.cacheData.loginUsers.filter((u) => u?.id));
4236
+ }
4237
+ getRefreshToken() {
4238
+ const cacheData = this.cacheData;
4239
+ return Promise.resolve(cacheData.refreshToken || "");
4240
+ }
4241
+ getAccessToken() {
4242
+ const cacheData = this.cacheData;
4243
+ return Promise.resolve(cacheData.accessToken || "");
4244
+ }
4245
+ async clearCurrentUser() {
4246
+ const user = await this.getCurrentUser();
4247
+ const has = this.cacheData.loginUsers.find((u) => u.id === user.id);
4248
+ if (has) {
4249
+ this.cacheData.loginUsers = this.cacheData?.loginUsers?.filter((u) => u?.id && u.id !== user.id);
4250
+ }
4251
+ this.cacheData.user = undefined;
4252
+ this.cacheData.id = undefined;
4253
+ this.cacheData.accessToken = undefined;
4254
+ this.cacheData.refreshToken = undefined;
4255
+ await this.setValue(this.cacheData);
4256
+ }
4257
+ async clearAll() {
4258
+ this.cacheData.loginUsers = [];
4259
+ this.cacheData.user = undefined;
4260
+ this.cacheData.id = undefined;
4261
+ this.cacheData.accessToken = undefined;
4262
+ this.cacheData.refreshToken = undefined;
4263
+ await this.setValue(this.cacheData);
4264
+ }
4265
+ }
4266
+
4267
+ // ../../node_modules/.pnpm/@kevisual+load@0.0.6/node_modules/@kevisual/load/dist/load.js
4268
+ function getDefaultExportFromCjs(x) {
4269
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
4270
+ }
4271
+ var eventemitter3 = { exports: {} };
4272
+ var hasRequiredEventemitter3;
4273
+ function requireEventemitter3() {
4274
+ if (hasRequiredEventemitter3)
4275
+ return eventemitter3.exports;
4276
+ hasRequiredEventemitter3 = 1;
4277
+ (function(module) {
4278
+ var has = Object.prototype.hasOwnProperty, prefix = "~";
4279
+ function Events() {}
4280
+ if (Object.create) {
4281
+ Events.prototype = Object.create(null);
4282
+ if (!new Events().__proto__)
4283
+ prefix = false;
4284
+ }
4285
+ function EE(fn, context, once) {
4286
+ this.fn = fn;
4287
+ this.context = context;
4288
+ this.once = once || false;
4289
+ }
4290
+ function addListener(emitter, event, fn, context, once) {
4291
+ if (typeof fn !== "function") {
4292
+ throw new TypeError("The listener must be a function");
4293
+ }
4294
+ var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
4295
+ if (!emitter._events[evt])
4296
+ emitter._events[evt] = listener, emitter._eventsCount++;
4297
+ else if (!emitter._events[evt].fn)
4298
+ emitter._events[evt].push(listener);
4299
+ else
4300
+ emitter._events[evt] = [emitter._events[evt], listener];
4301
+ return emitter;
4302
+ }
4303
+ function clearEvent(emitter, evt) {
4304
+ if (--emitter._eventsCount === 0)
4305
+ emitter._events = new Events;
4306
+ else
4307
+ delete emitter._events[evt];
4308
+ }
4309
+ function EventEmitter2() {
4310
+ this._events = new Events;
4311
+ this._eventsCount = 0;
4312
+ }
4313
+ EventEmitter2.prototype.eventNames = function eventNames() {
4314
+ var names = [], events, name;
4315
+ if (this._eventsCount === 0)
4316
+ return names;
4317
+ for (name in events = this._events) {
4318
+ if (has.call(events, name))
4319
+ names.push(prefix ? name.slice(1) : name);
4320
+ }
4321
+ if (Object.getOwnPropertySymbols) {
4322
+ return names.concat(Object.getOwnPropertySymbols(events));
4323
+ }
4324
+ return names;
4325
+ };
4326
+ EventEmitter2.prototype.listeners = function listeners(event) {
4327
+ var evt = prefix ? prefix + event : event, handlers = this._events[evt];
4328
+ if (!handlers)
4329
+ return [];
4330
+ if (handlers.fn)
4331
+ return [handlers.fn];
4332
+ for (var i = 0, l = handlers.length, ee = new Array(l);i < l; i++) {
4333
+ ee[i] = handlers[i].fn;
4334
+ }
4335
+ return ee;
4336
+ };
4337
+ EventEmitter2.prototype.listenerCount = function listenerCount(event) {
4338
+ var evt = prefix ? prefix + event : event, listeners = this._events[evt];
4339
+ if (!listeners)
4340
+ return 0;
4341
+ if (listeners.fn)
4342
+ return 1;
4343
+ return listeners.length;
4344
+ };
4345
+ EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
4346
+ var evt = prefix ? prefix + event : event;
4347
+ if (!this._events[evt])
4348
+ return false;
4349
+ var listeners = this._events[evt], len = arguments.length, args, i;
4350
+ if (listeners.fn) {
4351
+ if (listeners.once)
4352
+ this.removeListener(event, listeners.fn, undefined, true);
4353
+ switch (len) {
4354
+ case 1:
4355
+ return listeners.fn.call(listeners.context), true;
4356
+ case 2:
4357
+ return listeners.fn.call(listeners.context, a1), true;
4358
+ case 3:
4359
+ return listeners.fn.call(listeners.context, a1, a2), true;
4360
+ case 4:
4361
+ return listeners.fn.call(listeners.context, a1, a2, a3), true;
4362
+ case 5:
4363
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
4364
+ case 6:
4365
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
4366
+ }
4367
+ for (i = 1, args = new Array(len - 1);i < len; i++) {
4368
+ args[i - 1] = arguments[i];
4369
+ }
4370
+ listeners.fn.apply(listeners.context, args);
4371
+ } else {
4372
+ var length = listeners.length, j;
4373
+ for (i = 0;i < length; i++) {
4374
+ if (listeners[i].once)
4375
+ this.removeListener(event, listeners[i].fn, undefined, true);
4376
+ switch (len) {
4377
+ case 1:
4378
+ listeners[i].fn.call(listeners[i].context);
4379
+ break;
4380
+ case 2:
4381
+ listeners[i].fn.call(listeners[i].context, a1);
4382
+ break;
4383
+ case 3:
4384
+ listeners[i].fn.call(listeners[i].context, a1, a2);
4385
+ break;
4386
+ case 4:
4387
+ listeners[i].fn.call(listeners[i].context, a1, a2, a3);
4388
+ break;
4389
+ default:
4390
+ if (!args)
4391
+ for (j = 1, args = new Array(len - 1);j < len; j++) {
4392
+ args[j - 1] = arguments[j];
4393
+ }
4394
+ listeners[i].fn.apply(listeners[i].context, args);
4395
+ }
4396
+ }
4397
+ }
4398
+ return true;
4399
+ };
4400
+ EventEmitter2.prototype.on = function on(event, fn, context) {
4401
+ return addListener(this, event, fn, context, false);
4402
+ };
4403
+ EventEmitter2.prototype.once = function once(event, fn, context) {
4404
+ return addListener(this, event, fn, context, true);
4405
+ };
4406
+ EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) {
4407
+ var evt = prefix ? prefix + event : event;
4408
+ if (!this._events[evt])
4409
+ return this;
4410
+ if (!fn) {
4411
+ clearEvent(this, evt);
4412
+ return this;
4413
+ }
4414
+ var listeners = this._events[evt];
4415
+ if (listeners.fn) {
4416
+ if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
4417
+ clearEvent(this, evt);
4418
+ }
4419
+ } else {
4420
+ for (var i = 0, events = [], length = listeners.length;i < length; i++) {
4421
+ if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
4422
+ events.push(listeners[i]);
4423
+ }
4424
+ }
4425
+ if (events.length)
4426
+ this._events[evt] = events.length === 1 ? events[0] : events;
4427
+ else
4428
+ clearEvent(this, evt);
4429
+ }
4430
+ return this;
4431
+ };
4432
+ EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) {
4433
+ var evt;
4434
+ if (event) {
4435
+ evt = prefix ? prefix + event : event;
4436
+ if (this._events[evt])
4437
+ clearEvent(this, evt);
4438
+ } else {
4439
+ this._events = new Events;
4440
+ this._eventsCount = 0;
4441
+ }
4442
+ return this;
4443
+ };
4444
+ EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
4445
+ EventEmitter2.prototype.addListener = EventEmitter2.prototype.on;
4446
+ EventEmitter2.prefixed = prefix;
4447
+ EventEmitter2.EventEmitter = EventEmitter2;
4448
+ {
4449
+ module.exports = EventEmitter2;
4450
+ }
4451
+ })(eventemitter3);
4452
+ return eventemitter3.exports;
4453
+ }
4454
+ var eventemitter3Exports = requireEventemitter3();
4455
+ var EventEmitter2 = /* @__PURE__ */ getDefaultExportFromCjs(eventemitter3Exports);
4456
+ var reRunFn = (promiseOpts) => {
4457
+ const timeout = promiseOpts.timeout || 5 * 60 * 1000;
4458
+ const interval = promiseOpts.interval || 1000;
4459
+ const checkSuccess = promiseOpts?.checkSuccess || (() => true);
4460
+ const signal = promiseOpts.signal;
4461
+ return new Promise(async (resolve, reject) => {
4462
+ let intervalId;
4463
+ let timeoutId = setTimeout(() => {
4464
+ clearTimeout(intervalId);
4465
+ resolve({
4466
+ code: 500,
4467
+ message: "timeout"
4468
+ });
4469
+ }, timeout);
4470
+ const fn = promiseOpts.fn || (() => true);
4471
+ const runFn = async () => {
4472
+ if (signal?.aborted) {
4473
+ clearInterval(intervalId);
4474
+ clearTimeout(timeoutId);
4475
+ return resolve({
4476
+ code: 499,
4477
+ message: "operation cancelled"
4478
+ });
4479
+ }
4480
+ const res = await fn();
4481
+ if (!!checkSuccess(res)) {
4482
+ clearInterval(intervalId);
4483
+ clearTimeout(timeoutId);
4484
+ resolve({
4485
+ code: 200,
4486
+ data: res
4487
+ });
4488
+ } else {
4489
+ setTimeout(() => {
4490
+ runFn();
4491
+ }, interval);
4492
+ }
4493
+ };
4494
+ if (signal) {
4495
+ signal.addEventListener("abort", () => {
4496
+ clearInterval(intervalId);
4497
+ clearTimeout(timeoutId);
4498
+ resolve({
4499
+ code: 499,
4500
+ message: "operation cancelled"
4501
+ });
4502
+ });
4503
+ }
4504
+ runFn();
4505
+ });
4506
+ };
4507
+
4508
+ class BaseLoad {
4509
+ modules = new Map;
4510
+ event;
4511
+ loading;
4512
+ static reRunFn = reRunFn;
4513
+ timeout = 5 * 60 * 1000;
4514
+ constructor() {
4515
+ this.event = new EventEmitter2;
4516
+ this.loading = false;
4517
+ }
4518
+ listenKey(key, listenOpts) {
4519
+ const timeout = listenOpts?.timeout ?? this.timeout;
4520
+ return new Promise((resolve) => {
4521
+ const timeoutId = setTimeout(() => {
4522
+ this.event.removeListener(key, onEvent);
4523
+ resolve({
4524
+ code: 500,
4525
+ message: "timeout"
4526
+ });
4527
+ }, timeout);
4528
+ const onEvent = (error) => {
4529
+ clearTimeout(timeoutId);
4530
+ if (error) {
4531
+ return resolve({
4532
+ code: 500,
4533
+ message: error
4534
+ });
4535
+ }
4536
+ const data = this.modules.get(key);
4537
+ if (data?.loadSuccessClear) {
4538
+ this.remove(key);
4539
+ }
4540
+ resolve({
4541
+ code: 200,
4542
+ data: data?.modules
4543
+ });
4544
+ };
4545
+ this.event.once(key, onEvent);
4546
+ });
4547
+ }
4548
+ async hasLoaded(key, hasLoadOpts) {
4549
+ if (!key) {
4550
+ return {
4551
+ code: 404,
4552
+ message: "key is required"
4553
+ };
4554
+ }
4555
+ const has = this.modules.has(key);
4556
+ if (!has) {
4557
+ const isExist = hasLoadOpts?.isExist ?? true;
4558
+ const timeout = hasLoadOpts?.timeout ?? this.timeout;
4559
+ if (isExist) {
4560
+ return await this.listenKey(key, { timeout });
4561
+ }
4562
+ return {
4563
+ code: 404
4564
+ };
4565
+ }
4566
+ const data = this.modules.get(key);
4567
+ if (data?.status === "loaded") {
4568
+ return {
4569
+ code: 200,
4570
+ data: data.modules
4571
+ };
4572
+ }
4573
+ if (data?.status === "loading") {
4574
+ return await this.listenKey(key, { timeout: hasLoadOpts?.timeout ?? this.timeout });
4575
+ }
4576
+ if (data?.status === "error") {
4577
+ return {
4578
+ code: 500,
4579
+ message: "load error"
4580
+ };
4581
+ }
4582
+ if (data?.status === "cancel") {
4583
+ return {
4584
+ code: 499,
4585
+ message: "operation cancelled"
4586
+ };
4587
+ }
4588
+ return {
4589
+ code: 404
4590
+ };
4591
+ }
4592
+ async loadFn(loadContent, opts) {
4593
+ const key = opts.key;
4594
+ if (!key) {
4595
+ return {
4596
+ code: 404,
4597
+ message: "key is required"
4598
+ };
4599
+ }
4600
+ const newModule = {
4601
+ key: opts.key,
4602
+ status: "loading",
4603
+ loading: true,
4604
+ loadSuccessClear: opts.loadSuccessClear ?? true
4605
+ };
4606
+ let errorMessage = "";
4607
+ try {
4608
+ const isReRun = opts.isReRun ?? false;
4609
+ let res;
4610
+ if (!isReRun) {
4611
+ this.modules.set(key, newModule);
4612
+ res = await loadContent();
4613
+ } else {
4614
+ newModule.controller = new AbortController;
4615
+ const signal = newModule.controller.signal;
4616
+ this.modules.set(key, newModule);
4617
+ const data = await reRunFn({
4618
+ timeout: opts.timeout,
4619
+ interval: opts.interval,
4620
+ checkSuccess: opts.checkSuccess,
4621
+ fn: loadContent,
4622
+ signal
4623
+ });
4624
+ newModule.controller = null;
4625
+ if (data.code === 499) {
4626
+ newModule.status = "cancel";
4627
+ return {
4628
+ code: 499,
4629
+ message: "operation cancelled"
4630
+ };
4631
+ }
4632
+ if (data.code !== 200) {
4633
+ throw new Error(data.message);
4634
+ }
4635
+ res = data.data;
4636
+ }
4637
+ newModule.modules = res;
4638
+ newModule.status = "loaded";
4639
+ return {
4640
+ code: 200,
4641
+ data: res
4642
+ };
4643
+ } catch (error) {
4644
+ errorMessage = error.message;
4645
+ newModule.status = "error";
4646
+ return {
4647
+ code: 500,
4648
+ message: error
4649
+ };
4650
+ } finally {
4651
+ newModule.loading = false;
4652
+ this.modules.set(opts.key, newModule);
4653
+ if (!errorMessage) {
4654
+ this.event.emit(opts.key);
4655
+ } else {
4656
+ this.event.emit(opts.key, errorMessage);
4657
+ }
4658
+ }
4659
+ }
4660
+ async load(loadContent, opts) {
4661
+ this.loading = true;
4662
+ const key = opts.key;
4663
+ if (!key) {
4664
+ return {
4665
+ code: 404,
4666
+ message: "key is required"
4667
+ };
4668
+ }
4669
+ if (opts?.force) {
4670
+ this.remove(key);
4671
+ }
4672
+ const has = this.modules.has(key);
4673
+ if (has) {
4674
+ return await this.hasLoaded(key);
4675
+ }
4676
+ if (typeof loadContent === "function") {
4677
+ return this.loadFn(loadContent, opts);
4678
+ }
4679
+ console.error("loadContent is not a function and not has loaded");
4680
+ }
4681
+ remove(key) {
4682
+ const has = this.modules.has(key);
4683
+ if (has) {
4684
+ this.checkRemoveController(key);
4685
+ this.modules.delete(key);
4686
+ }
4687
+ }
4688
+ emitLoaded(key) {
4689
+ this.checkRemoveController(key);
4690
+ this.event.emit(key);
4691
+ }
4692
+ setModule(key, data, loadData) {
4693
+ const newModule = {
4694
+ key,
4695
+ status: "loaded",
4696
+ loading: false,
4697
+ modules: data || {},
4698
+ ...loadData
4699
+ };
4700
+ this.modules.set(key, newModule);
4701
+ this.emitLoaded(key);
4702
+ return newModule;
4703
+ }
4704
+ cancel(key) {
4705
+ this.checkRemoveController(key);
4706
+ }
4707
+ checkRemoveController(key) {
4708
+ const data = this.modules.get(key);
4709
+ if (data?.controller) {
4710
+ data.controller?.abort?.();
4711
+ delete data.controller;
4712
+ this.modules.set(key, data);
4713
+ }
4714
+ }
4715
+ }
4716
+
4717
+ // ../../node_modules/.pnpm/@kevisual+api@0.0.8/node_modules/@kevisual/api/query/query-login/query-login.ts
4718
+ class QueryLogin2 extends BaseQuery {
4719
+ cacheStore;
4720
+ isBrowser;
4721
+ load;
4722
+ storage;
4723
+ onLoad;
4724
+ constructor(opts) {
4725
+ super({
4726
+ query: opts?.query || new Query
4727
+ });
4728
+ this.cacheStore = new LoginCacheStore2({ name: "login", cache: opts?.cache });
4729
+ this.isBrowser = opts?.isBrowser ?? true;
4730
+ this.init();
4731
+ this.onLoad = opts?.onLoad;
4732
+ this.storage = opts?.storage || localStorage;
4733
+ }
4734
+ setQuery(query2) {
4735
+ this.query = query2;
4736
+ }
4737
+ async init() {
4738
+ await this.cacheStore.init();
4739
+ this.load = true;
4740
+ this.onLoad?.();
4741
+ }
4742
+ async post(data, opts) {
4743
+ try {
4744
+ return this.query.post({ path: "user", ...data }, opts);
4745
+ } catch (error) {
4746
+ console.log("error", error);
4747
+ return {
4748
+ code: 400
4749
+ };
4750
+ }
4751
+ }
4752
+ async login(data) {
4753
+ const res = await this.post({ key: "login", ...data });
4754
+ if (res.code === 200) {
4755
+ const { accessToken, refreshToken } = res?.data || {};
4756
+ this.storage.setItem("token", accessToken || "");
4757
+ await this.beforeSetLoginUser({ accessToken, refreshToken });
4758
+ }
4759
+ return res;
4760
+ }
4761
+ async loginByCode(data) {
4762
+ const res = await this.post({ path: "sms", key: "login", data });
4763
+ if (res.code === 200) {
4764
+ const { accessToken, refreshToken } = res?.data || {};
4765
+ this.storage.setItem("token", accessToken || "");
4766
+ await this.beforeSetLoginUser({ accessToken, refreshToken });
4767
+ }
4768
+ return res;
4769
+ }
4770
+ async setLoginToken(token) {
4771
+ const { accessToken, refreshToken } = token;
4772
+ this.storage.setItem("token", accessToken || "");
4773
+ await this.beforeSetLoginUser({ accessToken, refreshToken });
4774
+ }
4775
+ async loginByWechat(data) {
4776
+ const res = await this.post({ path: "wx", key: "open-login", code: data.code });
4777
+ if (res.code === 200) {
4778
+ const { accessToken, refreshToken } = res?.data || {};
4779
+ this.storage.setItem("token", accessToken || "");
4780
+ await this.beforeSetLoginUser({ accessToken, refreshToken });
4781
+ }
4782
+ return res;
4783
+ }
4784
+ async checkWechat({ onSuccess, onError }) {
4785
+ const url = new URL(window.location.href);
4786
+ const code = url.searchParams.get("code");
4787
+ const state = url.searchParams.get("state");
4788
+ if (code && state) {
4789
+ const res = await this.loginByWechat({ code });
4790
+ if (res.code === 200) {
4791
+ onSuccess?.(res.data);
4792
+ } else {
4793
+ onError?.(res);
4794
+ }
4795
+ }
4796
+ }
4797
+ async beforeSetLoginUser({ accessToken, refreshToken, check401 }) {
4798
+ if (accessToken && refreshToken) {
4799
+ const resUser = await this.getMe(accessToken, check401);
4800
+ if (resUser.code === 200) {
4801
+ const user = resUser.data;
4802
+ if (user) {
4803
+ this.cacheStore.setLoginUser({
4804
+ user,
4805
+ id: user.id,
4806
+ accessToken,
4807
+ refreshToken
4808
+ });
4809
+ } else {
4810
+ console.error("登录失败");
4811
+ }
4812
+ }
4813
+ }
4814
+ }
4815
+ async queryRefreshToken(refreshToken) {
4816
+ const _refreshToken = refreshToken || this.cacheStore.getRefreshToken();
4817
+ let data = { refreshToken: _refreshToken };
4818
+ if (!_refreshToken) {
4819
+ await this.cacheStore.clearCurrentUser();
4820
+ return {
4821
+ code: 401,
4822
+ message: "请先登录",
4823
+ data: {}
4824
+ };
4825
+ }
4826
+ return this.post({ key: "refreshToken", data }, {
4827
+ afterResponse: async (response, ctx) => {
4828
+ setBaseResponse(response);
4829
+ return response;
4830
+ }
4831
+ });
4832
+ }
4833
+ async afterCheck401ToRefreshToken(response, ctx, refetch) {
4834
+ const that = this;
4835
+ if (response?.code === 401) {
4836
+ const hasRefreshToken = await that.cacheStore.getRefreshToken();
4837
+ if (hasRefreshToken) {
4838
+ const res = await that.queryRefreshToken(hasRefreshToken);
4839
+ if (res.code === 200) {
4840
+ const { accessToken, refreshToken } = res?.data || {};
4841
+ that.storage.setItem("token", accessToken || "");
4842
+ await that.beforeSetLoginUser({ accessToken, refreshToken, check401: false });
4843
+ if (refetch && ctx && ctx.req && ctx.req.url && ctx.fetch) {
4844
+ await new Promise((resolve) => setTimeout(resolve, 1500));
4845
+ const url = ctx.req?.url;
4846
+ const body = ctx.req?.body;
4847
+ const headers = ctx.req?.headers;
4848
+ const res2 = await ctx.fetch(url, {
4849
+ method: "POST",
4850
+ body,
4851
+ headers: { ...headers, Authorization: `Bearer ${accessToken}` }
4852
+ });
4853
+ setBaseResponse(res2);
4854
+ return res2;
4855
+ }
4856
+ } else {
4857
+ that.storage.removeItem("token");
4858
+ await that.cacheStore.clearCurrentUser();
4859
+ }
4860
+ return res;
4861
+ }
4862
+ }
4863
+ return response;
4864
+ }
4865
+ async run401Action(response, ctx, opts) {
4866
+ const that = this;
4867
+ const refetch = opts?.refetch ?? false;
4868
+ if (response?.code === 401) {
4869
+ if (that.query.stop === true) {
4870
+ return { code: 500, success: false, message: "refresh token loading..." };
4871
+ }
4872
+ that.query.stop = true;
4873
+ const res = await that.afterCheck401ToRefreshToken(response, ctx, refetch);
4874
+ that.query.stop = false;
4875
+ opts?.afterCheck?.(res);
4876
+ if (res.code === 401) {
4877
+ opts?.afterAlso401?.(res);
4878
+ }
4879
+ return res;
4880
+ } else {
4881
+ return response;
4882
+ }
4883
+ }
4884
+ async getMe(token, check401 = true) {
4885
+ const _token = token || this.storage.getItem("token");
4886
+ const that = this;
4887
+ return that.post({ key: "me" }, {
4888
+ beforeRequest: async (config) => {
4889
+ if (config.headers) {
4890
+ config.headers["Authorization"] = `Bearer ${_token}`;
4891
+ }
4892
+ if (!_token) {
4893
+ return false;
4894
+ }
4895
+ return config;
4896
+ },
4897
+ afterResponse: async (response, ctx) => {
4898
+ if (response?.code === 401 && check401 && !token) {
4899
+ return await that.afterCheck401ToRefreshToken(response, ctx);
4900
+ }
4901
+ return response;
4902
+ }
4903
+ });
4904
+ }
4905
+ async checkLocalUser() {
4906
+ const user = await this.cacheStore.getCurrentUser();
4907
+ if (user) {
4908
+ return user;
4909
+ }
4910
+ return null;
4911
+ }
4912
+ async checkLocalToken() {
4913
+ const token = this.storage.getItem("token");
4914
+ return !!token;
4915
+ }
4916
+ async getToken() {
4917
+ const token = this.storage.getItem("token");
4918
+ return token || "";
4919
+ }
4920
+ async beforeRequest(opts = {}) {
4921
+ const token = this.storage.getItem("token");
4922
+ if (token) {
4923
+ opts.headers = { ...opts.headers, Authorization: `Bearer ${token}` };
4924
+ }
4925
+ return opts;
4926
+ }
4927
+ async postSwitchUser(username) {
4928
+ return this.post({ key: "switchCheck", data: { username } });
4929
+ }
4930
+ async switchUser(username) {
4931
+ const localUserList = await this.cacheStore.getCurrentUserList();
4932
+ const user = localUserList.find((userItem) => userItem.user.username === username);
4933
+ if (user) {
4934
+ this.storage.setItem("token", user.accessToken || "");
4935
+ await this.beforeSetLoginUser({ accessToken: user.accessToken, refreshToken: user.refreshToken });
4936
+ return {
4937
+ code: 200,
4938
+ data: {
4939
+ accessToken: user.accessToken,
4940
+ refreshToken: user.refreshToken
4941
+ },
4942
+ success: true,
4943
+ message: "切换用户成功"
4944
+ };
4945
+ }
4946
+ const res = await this.postSwitchUser(username);
4947
+ if (res.code === 200) {
4948
+ const { accessToken, refreshToken } = res?.data || {};
4949
+ this.storage.setItem("token", accessToken || "");
4950
+ await this.beforeSetLoginUser({ accessToken, refreshToken });
4951
+ }
4952
+ return res;
4953
+ }
4954
+ async logout() {
4955
+ this.storage.removeItem("token");
4956
+ const users = await this.cacheStore.getCurrentUserList();
4957
+ const tokens = users.map((user) => {
4958
+ return user?.accessToken;
4959
+ }).filter(Boolean);
4960
+ this.cacheStore.delValue();
4961
+ return this.post({ key: "logout", data: { tokens } });
4962
+ }
4963
+ async hasUser(username) {
4964
+ const that = this;
4965
+ return this.post({
4966
+ path: "org",
4967
+ key: "hasUser",
4968
+ data: {
4969
+ username
4970
+ }
4971
+ }, {
4972
+ afterResponse: async (response, ctx) => {
4973
+ if (response?.code === 401) {
4974
+ const res = await that.afterCheck401ToRefreshToken(response, ctx, true);
4975
+ return res;
4976
+ }
4977
+ return response;
4978
+ }
4979
+ });
4980
+ }
4981
+ async checkLoginStatus(token) {
4982
+ const res = await this.post({
4983
+ path: "user",
4984
+ key: "checkLoginStatus",
4985
+ loginToken: token
4986
+ });
4987
+ if (res.code === 200) {
4988
+ const accessToken = res.data?.accessToken;
4989
+ this.storage.setItem("token", accessToken || "");
4990
+ await this.beforeSetLoginUser({ accessToken, refreshToken: res.data?.refreshToken });
4991
+ return res;
4992
+ }
4993
+ return false;
4994
+ }
4995
+ loginWithWeb(baseURL, { MD5, jsonwebtoken }) {
4996
+ const randomId = Math.random().toString(36).substring(2, 15);
4997
+ const timestamp = Date.now();
4998
+ const tokenSecret = "xiao" + randomId;
4999
+ let sign = "";
5000
+ if (MD5) {
5001
+ sign = MD5(`${tokenSecret}${timestamp}`).toString();
5002
+ }
5003
+ let token = "";
5004
+ if (jsonwebtoken) {
5005
+ token = jsonwebtoken.sign({ randomId, timestamp, sign }, tokenSecret, {
5006
+ expiresIn: 60 * 10
5007
+ });
5008
+ } else {
5009
+ token = tokenSecret;
5010
+ }
5011
+ const url = `${baseURL}/api/router?path=user&key=webLogin&p&loginToken=${token}&sign=${sign}&randomId=${randomId}`;
5012
+ return { url, token, tokenSecret };
5013
+ }
5014
+ async pollLoginStatus(data) {
5015
+ const token = data.token;
5016
+ const load = new BaseLoad;
5017
+ load.load(async () => {
5018
+ const res2 = await this.checkLoginStatus(token);
5019
+ if (res2.code === 500) {
5020
+ load.cancel("check-login-status");
5021
+ }
5022
+ return res2;
5023
+ }, {
5024
+ key: "check-login-status",
5025
+ isReRun: true,
5026
+ checkSuccess: (data2) => {
5027
+ return data2?.code === 200;
5028
+ }
5029
+ });
5030
+ const res = await load.hasLoaded("check-login-status", {
5031
+ timeout: 60 * 3 * 1000
5032
+ });
5033
+ if (res.code === 200 && res.data?.code === 200) {
5034
+ try {
5035
+ console.log("网页登录成功");
5036
+ return true;
5037
+ } catch (error) {
5038
+ console.log("登录失败", error);
5039
+ return false;
5040
+ }
5041
+ }
5042
+ console.log("登录失败", res);
5043
+ return false;
5044
+ }
5045
+ }
5046
+
5047
+ // ../../node_modules/.pnpm/@kevisual+api@0.0.8/node_modules/@kevisual/api/query/query-login/query-login-browser.ts
5048
+ class QueryLoginBrowser2 extends QueryLogin2 {
5049
+ constructor(opts) {
5050
+ super({
5051
+ ...opts,
5052
+ cache: new MyCache("login")
5053
+ });
5054
+ }
5055
+ }
5056
+
4169
5057
  // src/modules/login-handle.ts
4170
5058
  var message = createMessage();
4171
5059
  var redirectHome = () => {
@@ -4196,10 +5084,27 @@ var loginHandle = async (opts) => {
4196
5084
  case "wechat":
4197
5085
  await loginByWeChat(data);
4198
5086
  break;
5087
+ case "web":
5088
+ await loginByWeb(data);
5089
+ break;
4199
5090
  default:
4200
5091
  console.warn("未知的登录方式:", loginMethod);
4201
5092
  }
4202
5093
  };
5094
+ var loginByWeb = async (data) => {
5095
+ const url = new URL("https://kevisual.cn/api/router");
5096
+ const query2 = new Query({ url: "https://kevisual.cn/api/router" });
5097
+ const login = new QueryLoginBrowser2({ query: query2 });
5098
+ const res = login.loginWithWeb(url.origin, {});
5099
+ console.log("打开网页登录:", res);
5100
+ window.open(res.url, "_blank");
5101
+ const status = await login.pollLoginStatus(res);
5102
+ if (status) {
5103
+ redirectHome();
5104
+ } else {
5105
+ message.error("网页登录失败,请重试");
5106
+ }
5107
+ };
4203
5108
  var loginByPassword = async (data) => {
4204
5109
  console.log("使用用户名密码登录:", data);
4205
5110
  let needLogin = true;
@@ -4507,15 +5412,15 @@ var useCreateLoginQRCode = (el) => {
4507
5412
 
4508
5413
  // ../../node_modules/.pnpm/@kevisual+context@0.0.4/node_modules/@kevisual/context/dist/app.js
4509
5414
  var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
4510
- function getDefaultExportFromCjs(x) {
5415
+ function getDefaultExportFromCjs2(x) {
4511
5416
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
4512
5417
  }
4513
- var eventemitter3 = { exports: {} };
4514
- var hasRequiredEventemitter3;
4515
- function requireEventemitter3() {
4516
- if (hasRequiredEventemitter3)
4517
- return eventemitter3.exports;
4518
- hasRequiredEventemitter3 = 1;
5418
+ var eventemitter32 = { exports: {} };
5419
+ var hasRequiredEventemitter32;
5420
+ function requireEventemitter32() {
5421
+ if (hasRequiredEventemitter32)
5422
+ return eventemitter32.exports;
5423
+ hasRequiredEventemitter32 = 1;
4519
5424
  (function(module) {
4520
5425
  var has = Object.prototype.hasOwnProperty, prefix = "~";
4521
5426
  function Events() {}
@@ -4548,11 +5453,11 @@ function requireEventemitter3() {
4548
5453
  else
4549
5454
  delete emitter._events[evt];
4550
5455
  }
4551
- function EventEmitter2() {
5456
+ function EventEmitter3() {
4552
5457
  this._events = new Events;
4553
5458
  this._eventsCount = 0;
4554
5459
  }
4555
- EventEmitter2.prototype.eventNames = function eventNames() {
5460
+ EventEmitter3.prototype.eventNames = function eventNames() {
4556
5461
  var names = [], events, name;
4557
5462
  if (this._eventsCount === 0)
4558
5463
  return names;
@@ -4565,7 +5470,7 @@ function requireEventemitter3() {
4565
5470
  }
4566
5471
  return names;
4567
5472
  };
4568
- EventEmitter2.prototype.listeners = function listeners(event) {
5473
+ EventEmitter3.prototype.listeners = function listeners(event) {
4569
5474
  var evt = prefix ? prefix + event : event, handlers = this._events[evt];
4570
5475
  if (!handlers)
4571
5476
  return [];
@@ -4576,7 +5481,7 @@ function requireEventemitter3() {
4576
5481
  }
4577
5482
  return ee;
4578
5483
  };
4579
- EventEmitter2.prototype.listenerCount = function listenerCount(event) {
5484
+ EventEmitter3.prototype.listenerCount = function listenerCount(event) {
4580
5485
  var evt = prefix ? prefix + event : event, listeners = this._events[evt];
4581
5486
  if (!listeners)
4582
5487
  return 0;
@@ -4584,7 +5489,7 @@ function requireEventemitter3() {
4584
5489
  return 1;
4585
5490
  return listeners.length;
4586
5491
  };
4587
- EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
5492
+ EventEmitter3.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
4588
5493
  var evt = prefix ? prefix + event : event;
4589
5494
  if (!this._events[evt])
4590
5495
  return false;
@@ -4639,13 +5544,13 @@ function requireEventemitter3() {
4639
5544
  }
4640
5545
  return true;
4641
5546
  };
4642
- EventEmitter2.prototype.on = function on(event, fn, context) {
5547
+ EventEmitter3.prototype.on = function on(event, fn, context) {
4643
5548
  return addListener(this, event, fn, context, false);
4644
5549
  };
4645
- EventEmitter2.prototype.once = function once(event, fn, context) {
5550
+ EventEmitter3.prototype.once = function once(event, fn, context) {
4646
5551
  return addListener(this, event, fn, context, true);
4647
5552
  };
4648
- EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) {
5553
+ EventEmitter3.prototype.removeListener = function removeListener(event, fn, context, once) {
4649
5554
  var evt = prefix ? prefix + event : event;
4650
5555
  if (!this._events[evt])
4651
5556
  return this;
@@ -4671,7 +5576,7 @@ function requireEventemitter3() {
4671
5576
  }
4672
5577
  return this;
4673
5578
  };
4674
- EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) {
5579
+ EventEmitter3.prototype.removeAllListeners = function removeAllListeners(event) {
4675
5580
  var evt;
4676
5581
  if (event) {
4677
5582
  evt = prefix ? prefix + event : event;
@@ -4683,19 +5588,19 @@ function requireEventemitter3() {
4683
5588
  }
4684
5589
  return this;
4685
5590
  };
4686
- EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
4687
- EventEmitter2.prototype.addListener = EventEmitter2.prototype.on;
4688
- EventEmitter2.prefixed = prefix;
4689
- EventEmitter2.EventEmitter = EventEmitter2;
5591
+ EventEmitter3.prototype.off = EventEmitter3.prototype.removeListener;
5592
+ EventEmitter3.prototype.addListener = EventEmitter3.prototype.on;
5593
+ EventEmitter3.prefixed = prefix;
5594
+ EventEmitter3.EventEmitter = EventEmitter3;
4690
5595
  {
4691
- module.exports = EventEmitter2;
5596
+ module.exports = EventEmitter3;
4692
5597
  }
4693
- })(eventemitter3);
4694
- return eventemitter3.exports;
5598
+ })(eventemitter32);
5599
+ return eventemitter32.exports;
4695
5600
  }
4696
- var eventemitter3Exports = requireEventemitter3();
4697
- var EventEmitter2 = /* @__PURE__ */ getDefaultExportFromCjs(eventemitter3Exports);
4698
- var reRunFn = (promiseOpts) => {
5601
+ var eventemitter3Exports2 = requireEventemitter32();
5602
+ var EventEmitter3 = /* @__PURE__ */ getDefaultExportFromCjs2(eventemitter3Exports2);
5603
+ var reRunFn2 = (promiseOpts) => {
4699
5604
  const timeout = promiseOpts.timeout || 5 * 60 * 1000;
4700
5605
  const interval = promiseOpts.interval || 1000;
4701
5606
  const checkSuccess = promiseOpts?.checkSuccess || (() => true);
@@ -4747,14 +5652,14 @@ var reRunFn = (promiseOpts) => {
4747
5652
  });
4748
5653
  };
4749
5654
 
4750
- class BaseLoad {
5655
+ class BaseLoad2 {
4751
5656
  modules = new Map;
4752
5657
  event;
4753
5658
  loading;
4754
- static reRunFn = reRunFn;
5659
+ static reRunFn = reRunFn2;
4755
5660
  timeout = 5 * 60 * 1000;
4756
5661
  constructor() {
4757
- this.event = new EventEmitter2;
5662
+ this.event = new EventEmitter3;
4758
5663
  this.loading = false;
4759
5664
  }
4760
5665
  listenKey(key, listenOpts) {
@@ -4856,7 +5761,7 @@ class BaseLoad {
4856
5761
  newModule.controller = new AbortController;
4857
5762
  const signal = newModule.controller.signal;
4858
5763
  this.modules.set(key, newModule);
4859
- const data = await reRunFn({
5764
+ const data = await reRunFn2({
4860
5765
  timeout: opts.timeout,
4861
5766
  interval: opts.interval,
4862
5767
  checkSuccess: opts.checkSuccess,
@@ -4992,7 +5897,7 @@ var useEnvKey = (key, init, initKey = "config") => {
4992
5897
  return _env[key];
4993
5898
  }
4994
5899
  if (key) {
4995
- const baseLoad = new BaseLoad;
5900
+ const baseLoad = new BaseLoad2;
4996
5901
  const voidFn = async () => {
4997
5902
  return _env[key];
4998
5903
  };
@@ -5051,7 +5956,7 @@ class InitEnv {
5051
5956
  gt.useContextKey = useContextKey;
5052
5957
  gt.use = use;
5053
5958
  gt.webEnv = { useConfigKey, useContextKey, use };
5054
- load && (gt.Load = BaseLoad);
5959
+ load && (gt.Load = BaseLoad2);
5055
5960
  }
5056
5961
  }
5057
5962
  InitEnv.init();
@@ -5063,26 +5968,29 @@ var wxmpSvg = `<svg t="1764510467010" class="icon" viewBox="0 0 1024 1024" versi
5063
5968
  var wxOpenSvg = `<svg t="1764511395617" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3882" width="32" height="32"><path d="M256 259.584c-29.184 0-51.2 14.848-51.2 44.032s29.184 44.032 51.2 44.032c29.184 0 44.032-14.848 44.032-44.032s-22.016-44.032-44.032-44.032zM541.184 303.616c0-29.184-14.848-44.032-44.032-44.032-29.184 0-51.2 14.848-51.2 44.032s29.184 44.032 51.2 44.032c29.696 0 44.032-22.016 44.032-44.032zM614.4 508.416c-14.848 0-36.352 14.848-36.352 36.352 0 14.848 14.848 36.352 36.352 36.352 29.184 0 44.032-14.848 44.032-36.352 0-14.336-14.848-36.352-44.032-36.352z" p-id="3883"></path><path d="M1024 625.152c0-138.752-124.416-256-285.184-270.848-29.184-153.6-189.952-263.168-373.248-263.168C160.768 91.648 0 230.4 0 406.016c0 95.232 44.032 175.616 138.752 241.152L109.568 742.4c0 7.168 0 14.848 7.168 22.016h14.848l117.248-58.368h14.848c36.352 7.168 66.048 14.848 109.568 14.848 14.848 0 44.032-7.168 44.032-7.168C460.8 822.784 578.048 896 716.8 896c36.352 0 73.216-7.168 102.4-14.848l87.552 51.2h14.848c7.168-7.168 7.168-7.168 7.168-14.848l-22.016-87.552c80.896-58.368 117.248-131.584 117.248-204.8z m-621.568 51.2h-36.352c-36.352 0-66.048-7.168-95.232-14.848l-22.016-7.168h-7.168L153.6 698.368l22.016-66.048c0-7.168 0-14.848-7.168-14.848C80.384 559.616 36.352 486.4 36.352 398.848 36.352 245.248 182.784 128 358.4 128c160.768 0 300.032 95.232 329.216 226.816-168.448 0-300.032 117.248-300.032 263.168 7.168 22.016 14.848 44.032 14.848 58.368z m467.968 132.096c-7.168 7.168-7.168 7.168-7.168 14.848l14.848 51.2L819.2 844.8h-14.848c-29.184 7.168-66.048 14.848-95.232 14.848-146.432 0-270.848-102.4-270.848-226.816 0-131.584 124.416-233.984 270.848-233.984s270.848 102.4 270.848 226.816c0 65.536-36.352 123.904-109.568 182.784z" p-id="3884"></path><path d="M804.352 508.416c-14.848 0-36.352 14.848-36.352 36.352 0 14.848 14.848 36.352 36.352 36.352 29.184 0 44.032-14.848 44.032-36.352 0-14.336-14.336-36.352-44.032-36.352z" p-id="3885"></path></svg>`;
5064
5969
  var phone = `<svg t="1764511425462" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5097" width="32" height="32"><path d="M820.409449 797.228346q0 25.19685-10.07874 46.866142t-27.716535 38.299213-41.322835 26.204724-50.897638 9.574803l-357.795276 0q-27.212598 0-50.897638-9.574803t-41.322835-26.204724-27.716535-38.299213-10.07874-46.866142l0-675.275591q0-25.19685 10.07874-47.370079t27.716535-38.80315 41.322835-26.204724 50.897638-9.574803l357.795276 0q27.212598 0 50.897638 9.574803t41.322835 26.204724 27.716535 38.80315 10.07874 47.370079l0 675.275591zM738.771654 170.330709l-455.559055 0 0 577.511811 455.559055 0 0-577.511811zM510.992126 776.062992q-21.165354 0-36.787402 15.11811t-15.622047 37.291339q0 21.165354 15.622047 36.787402t36.787402 15.622047q22.173228 0 37.291339-15.622047t15.11811-36.787402q0-22.173228-15.11811-37.291339t-37.291339-15.11811zM591.622047 84.661417q0-8.062992-5.03937-12.598425t-11.086614-4.535433l-128 0q-5.03937 0-10.582677 4.535433t-5.543307 12.598425 5.03937 12.598425 11.086614 4.535433l128 0q6.047244 0 11.086614-4.535433t5.03937-12.598425z" p-id="5098"></path></svg>`;
5065
5970
  var pwd = `<svg t="1764511500570" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10511" width="32" height="32"><path d="M768.9216 422.72768 372.06016 422.72768C378.88 365.21984 329.37984 131.42016 512.2048 125.72672c173.83424-6.59456 146.78016 213.34016 146.78016 213.34016l85.13536 0.57344c0 0 24.73984-294.4-231.91552-295.8336C232.09984 58.01984 297.82016 377.18016 289.28 422.72768c1.98656 0 4.56704 0 7.29088 0-55.88992 0-101.21216 45.34272-101.21216 101.21216l0 337.38752c0 55.88992 45.34272 101.21216 101.21216 101.21216l472.35072 0c55.88992 0 101.21216-45.34272 101.21216-101.21216L870.13376 523.93984C870.13376 468.0704 824.79104 422.72768 768.9216 422.72768zM566.4768 717.02528l0 76.84096c0 18.57536-15.1552 33.73056-33.73056 33.73056-18.57536 0-33.73056-15.1552-33.73056-33.73056l0-76.84096c-20.09088-11.69408-33.73056-33.21856-33.73056-58.12224 0-37.2736 30.208-67.4816 67.4816-67.4816 37.2736 0 67.4816 30.208 67.4816 67.4816C600.22784 683.80672 586.58816 705.3312 566.4768 717.02528z" fill="#272636" p-id="10512"></path></svg>`;
5971
+ var web = `<svg t="1764511538113" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11994" width="32" height="32"><path d="M512 85.333333C264.533333 85.333333 64 285.866667 64 533.333333s200.533333 448 448 448 448-200.533333 448-448S759.466667 85.333333 512 85.333333z m0 810.666667c-200.533333 0-362.666667-162.133333-362.666667-362.666667S311.466667 170.666667 512 170.666667s362.666667 162.133333 362.666667 362.666667-162.133333 362.666667-362.666667 362.666667z" p-id="11995"></path><path d="M512 298.666667c-119.466667 0-216.533333 97.066667-216.533333 216.533333s97.066667 216.533333 216.533333 216.533333 216.533333-97.066667 216.533333-216.533333-97.066667-216.533333-216.533333-216.533333z m0 362.666666c-80.853333 0-146.133333-65.28-146.133333-146.133333s65.28-146.133333 146.133333-146.133333 146.133333 65.28 146.133333 146.133333-65.28 146.133333-146.133333 146.133333z" p-id="11996"></path></svg>`;
5066
5972
  var icons = {
5067
5973
  pwd,
5974
+ web,
5068
5975
  phone,
5069
5976
  wxmpSvg,
5070
5977
  wxOpenSvg
5071
5978
  };
5072
5979
  var DefaultLoginMethods = [
5073
5980
  { id: "password", name: "密码登录", icon: "pwd" },
5981
+ { id: "web", name: "网页登录", icon: "web" },
5074
5982
  { id: "wechat", name: "微信登录", icon: "wxmpSvg", appid: "wx9378885c8390e09b" },
5075
5983
  { id: "wechat-mp", name: "微信公众号", icon: "wxOpenSvg", appid: WX_MP_APP_ID },
5076
5984
  { id: "wechat-mp-ticket", name: "微信公众号", icon: "wxOpenSvg" },
5077
5985
  { id: "phone", name: "手机号登录", icon: "phone" }
5078
5986
  ];
5079
- var LoginMethods = ["password", "phone", "wechat", "wechat-mp", "wechat-mp-ticket"];
5987
+ var LoginMethods = ["password", "web", "phone", "wechat", "wechat-mp", "wechat-mp-ticket"];
5080
5988
  var getLoginMethodByDomain = () => {
5081
5989
  let domain = window.location.host;
5082
5990
  let methods = [];
5083
- const has51015 = domain.includes("51015");
5084
- if (has51015) {
5085
- domain = "localhost:51015";
5991
+ const has51 = domain.includes("localhost") && (domain.endsWith("51515") || domain.endsWith("51015"));
5992
+ if (has51) {
5993
+ domain = "localhost";
5086
5994
  }
5087
5995
  switch (domain) {
5088
5996
  case "kevisual.xiongxiao.me":
@@ -5091,11 +5999,11 @@ var getLoginMethodByDomain = () => {
5091
5999
  case "kevisual.cn":
5092
6000
  methods = ["password", "wechat-mp-ticket", "wechat"];
5093
6001
  break;
5094
- case "localhost:51015":
5095
- methods = ["password"];
6002
+ case "localhost":
6003
+ methods = ["password", "web"];
5096
6004
  break;
5097
6005
  default:
5098
- methods = ["password", "phone", "wechat", "wechat-mp", "wechat-mp-ticket"];
6006
+ methods = ["password", "web", "phone", "wechat", "wechat-mp", "wechat-mp-ticket"];
5099
6007
  break;
5100
6008
  }
5101
6009
  return DefaultLoginMethods.filter((method) => methods.includes(method.id));
@@ -5196,6 +6104,8 @@ class KvLogin extends HTMLElement {
5196
6104
  username: username?.value || "",
5197
6105
  password: password?.value || ""
5198
6106
  };
6107
+ case "web":
6108
+ return {};
5199
6109
  case "phone":
5200
6110
  const phone2 = this.shadowRoot.querySelector("#phone");
5201
6111
  const code = this.shadowRoot.querySelector("#code");
@@ -5242,6 +6152,14 @@ class KvLogin extends HTMLElement {
5242
6152
  </form>
5243
6153
  `;
5244
6154
  }
6155
+ renderWebForm() {
6156
+ return html`
6157
+ <div class="web-login">
6158
+ <button type="button" class="refresh-button" @click=${this.handleLogin.bind(this)}>点击登录</button>
6159
+ <slot></slot>
6160
+ </div>
6161
+ `;
6162
+ }
5245
6163
  renderPhoneForm() {
5246
6164
  return html`
5247
6165
  <form id="loginForm" class="login-form">
@@ -5331,6 +6249,8 @@ class KvLogin extends HTMLElement {
5331
6249
  switch (this.selectedMethod) {
5332
6250
  case "password":
5333
6251
  return this.renderPasswordForm();
6252
+ case "web":
6253
+ return this.renderWebForm();
5334
6254
  case "phone":
5335
6255
  return this.renderPhoneForm();
5336
6256
  case "wechat":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevisual/kv-login",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "",
5
5
  "main": "src/main.ts",
6
6
  "scripts": {
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
21
21
  "license": "MIT",
22
- "packageManager": "pnpm@10.24.0",
22
+ "packageManager": "pnpm@10.26.2",
23
23
  "publishConfig": {
24
24
  "access": "public"
25
25
  },
@@ -27,7 +27,8 @@
27
27
  "dependencies": {
28
28
  "@kevisual/context": "^0.0.4",
29
29
  "@kevisual/query-login": "^0.0.7",
30
- "lit-html": "^3.3.1",
30
+ "crypto-js": "^4.2.0",
31
+ "lit-html": "^3.3.2",
31
32
  "qrcode": "^1.5.4"
32
33
  },
33
34
  "exports": {
@@ -36,6 +37,7 @@
36
37
  },
37
38
  "types": "./types/index.d.ts",
38
39
  "devDependencies": {
40
+ "@kevisual/api": "^0.0.8",
39
41
  "@types/bun": "^1.3.5"
40
42
  }
41
43
  }
@@ -2,9 +2,11 @@ import { query } from './query.ts';
2
2
  import { createMessage } from '../pages/kv-message.ts';
3
3
  import { WX_MP_APP_ID } from '../pages/kv-login.ts';
4
4
  import { emit } from './mitt.ts';
5
+ import { Query } from '@kevisual/query';
6
+ import { QueryLoginBrowser } from '@kevisual/api/login'
5
7
  export const message = createMessage();
6
8
  type LoginOpts = {
7
- loginMethod: 'password' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket',
9
+ loginMethod: 'password' | 'web' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket',
8
10
  data: any,
9
11
  el: HTMLElement
10
12
  }
@@ -40,10 +42,28 @@ export const loginHandle = async (opts: LoginOpts) => {
40
42
  case 'wechat':
41
43
  await loginByWeChat(data)
42
44
  break
45
+ case 'web':
46
+ await loginByWeb(data)
47
+ break
43
48
  default:
44
49
  console.warn('未知的登录方式:', loginMethod)
45
50
  }
46
51
  }
52
+ const loginByWeb = async (data: {}) => {
53
+ const url = new URL("https://kevisual.cn/api/router");
54
+ const query = new Query({ url: "https://kevisual.cn/api/router" })
55
+ const login = new QueryLoginBrowser({ query })
56
+ // @ts-ignore
57
+ const res = login.loginWithWeb(url.origin, {})
58
+ console.log('打开网页登录:', res)
59
+ window.open(res.url, '_blank');
60
+ const status = await login.pollLoginStatus(res);
61
+ if (status) {
62
+ redirectHome()
63
+ } else {
64
+ message.error('网页登录失败,请重试')
65
+ }
66
+ }
47
67
  /**
48
68
  * 使用用户名和密码登录
49
69
  * @param data
@@ -1,10 +1,11 @@
1
1
  import { render, html } from 'lit-html'
2
2
  import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'
3
- import { loginHandle, checkWechat, getQrCode, checkMpQrCodeLogin } from '../modules/login-handle.ts'
3
+ import { loginHandle, checkWechat, getQrCode, checkMpQrCodeLogin, redirectHome } from '../modules/login-handle.ts'
4
4
  import { setWxerwma } from '../modules/wx/ws-login.ts';
5
5
  import { useCreateLoginQRCode } from '../modules/wx-mp/qr.ts';
6
6
  import { eventEmitter } from '../modules/mitt.ts';
7
7
  import { useContextKey } from '@kevisual/context'
8
+
8
9
  export const loginEmitter = useContextKey('login-emitter', eventEmitter);
9
10
  export const WX_MP_APP_ID = "wxff97d569b1db16b6";
10
11
  interface LoginMethod {
@@ -17,29 +18,31 @@ const wxmpSvg = `<svg t="1764510467010" class="icon" viewBox="0 0 1024 1024" ver
17
18
  const wxOpenSvg = `<svg t="1764511395617" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3882" width="32" height="32"><path d="M256 259.584c-29.184 0-51.2 14.848-51.2 44.032s29.184 44.032 51.2 44.032c29.184 0 44.032-14.848 44.032-44.032s-22.016-44.032-44.032-44.032zM541.184 303.616c0-29.184-14.848-44.032-44.032-44.032-29.184 0-51.2 14.848-51.2 44.032s29.184 44.032 51.2 44.032c29.696 0 44.032-22.016 44.032-44.032zM614.4 508.416c-14.848 0-36.352 14.848-36.352 36.352 0 14.848 14.848 36.352 36.352 36.352 29.184 0 44.032-14.848 44.032-36.352 0-14.336-14.848-36.352-44.032-36.352z" p-id="3883"></path><path d="M1024 625.152c0-138.752-124.416-256-285.184-270.848-29.184-153.6-189.952-263.168-373.248-263.168C160.768 91.648 0 230.4 0 406.016c0 95.232 44.032 175.616 138.752 241.152L109.568 742.4c0 7.168 0 14.848 7.168 22.016h14.848l117.248-58.368h14.848c36.352 7.168 66.048 14.848 109.568 14.848 14.848 0 44.032-7.168 44.032-7.168C460.8 822.784 578.048 896 716.8 896c36.352 0 73.216-7.168 102.4-14.848l87.552 51.2h14.848c7.168-7.168 7.168-7.168 7.168-14.848l-22.016-87.552c80.896-58.368 117.248-131.584 117.248-204.8z m-621.568 51.2h-36.352c-36.352 0-66.048-7.168-95.232-14.848l-22.016-7.168h-7.168L153.6 698.368l22.016-66.048c0-7.168 0-14.848-7.168-14.848C80.384 559.616 36.352 486.4 36.352 398.848 36.352 245.248 182.784 128 358.4 128c160.768 0 300.032 95.232 329.216 226.816-168.448 0-300.032 117.248-300.032 263.168 7.168 22.016 14.848 44.032 14.848 58.368z m467.968 132.096c-7.168 7.168-7.168 7.168-7.168 14.848l14.848 51.2L819.2 844.8h-14.848c-29.184 7.168-66.048 14.848-95.232 14.848-146.432 0-270.848-102.4-270.848-226.816 0-131.584 124.416-233.984 270.848-233.984s270.848 102.4 270.848 226.816c0 65.536-36.352 123.904-109.568 182.784z" p-id="3884"></path><path d="M804.352 508.416c-14.848 0-36.352 14.848-36.352 36.352 0 14.848 14.848 36.352 36.352 36.352 29.184 0 44.032-14.848 44.032-36.352 0-14.336-14.336-36.352-44.032-36.352z" p-id="3885"></path></svg>`
18
19
  const phone = `<svg t="1764511425462" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5097" width="32" height="32"><path d="M820.409449 797.228346q0 25.19685-10.07874 46.866142t-27.716535 38.299213-41.322835 26.204724-50.897638 9.574803l-357.795276 0q-27.212598 0-50.897638-9.574803t-41.322835-26.204724-27.716535-38.299213-10.07874-46.866142l0-675.275591q0-25.19685 10.07874-47.370079t27.716535-38.80315 41.322835-26.204724 50.897638-9.574803l357.795276 0q27.212598 0 50.897638 9.574803t41.322835 26.204724 27.716535 38.80315 10.07874 47.370079l0 675.275591zM738.771654 170.330709l-455.559055 0 0 577.511811 455.559055 0 0-577.511811zM510.992126 776.062992q-21.165354 0-36.787402 15.11811t-15.622047 37.291339q0 21.165354 15.622047 36.787402t36.787402 15.622047q22.173228 0 37.291339-15.622047t15.11811-36.787402q0-22.173228-15.11811-37.291339t-37.291339-15.11811zM591.622047 84.661417q0-8.062992-5.03937-12.598425t-11.086614-4.535433l-128 0q-5.03937 0-10.582677 4.535433t-5.543307 12.598425 5.03937 12.598425 11.086614 4.535433l128 0q6.047244 0 11.086614-4.535433t5.03937-12.598425z" p-id="5098"></path></svg>`
19
20
  const pwd = `<svg t="1764511500570" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10511" width="32" height="32"><path d="M768.9216 422.72768 372.06016 422.72768C378.88 365.21984 329.37984 131.42016 512.2048 125.72672c173.83424-6.59456 146.78016 213.34016 146.78016 213.34016l85.13536 0.57344c0 0 24.73984-294.4-231.91552-295.8336C232.09984 58.01984 297.82016 377.18016 289.28 422.72768c1.98656 0 4.56704 0 7.29088 0-55.88992 0-101.21216 45.34272-101.21216 101.21216l0 337.38752c0 55.88992 45.34272 101.21216 101.21216 101.21216l472.35072 0c55.88992 0 101.21216-45.34272 101.21216-101.21216L870.13376 523.93984C870.13376 468.0704 824.79104 422.72768 768.9216 422.72768zM566.4768 717.02528l0 76.84096c0 18.57536-15.1552 33.73056-33.73056 33.73056-18.57536 0-33.73056-15.1552-33.73056-33.73056l0-76.84096c-20.09088-11.69408-33.73056-33.21856-33.73056-58.12224 0-37.2736 30.208-67.4816 67.4816-67.4816 37.2736 0 67.4816 30.208 67.4816 67.4816C600.22784 683.80672 586.58816 705.3312 566.4768 717.02528z" fill="#272636" p-id="10512"></path></svg>`
20
-
21
+ const web = `<svg t="1764511538113" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11994" width="32" height="32"><path d="M512 85.333333C264.533333 85.333333 64 285.866667 64 533.333333s200.533333 448 448 448 448-200.533333 448-448S759.466667 85.333333 512 85.333333z m0 810.666667c-200.533333 0-362.666667-162.133333-362.666667-362.666667S311.466667 170.666667 512 170.666667s362.666667 162.133333 362.666667 362.666667-162.133333 362.666667-362.666667 362.666667z" p-id="11995"></path><path d="M512 298.666667c-119.466667 0-216.533333 97.066667-216.533333 216.533333s97.066667 216.533333 216.533333 216.533333 216.533333-97.066667 216.533333-216.533333-97.066667-216.533333-216.533333-216.533333z m0 362.666666c-80.853333 0-146.133333-65.28-146.133333-146.133333s65.28-146.133333 146.133333-146.133333 146.133333 65.28 146.133333 146.133333-65.28 146.133333-146.133333 146.133333z" p-id="11996"></path></svg>`
21
22
  const icons: any = {
22
23
  pwd,
24
+ web,
23
25
  phone,
24
26
  wxmpSvg,
25
27
  wxOpenSvg
26
28
  }
27
29
  const DefaultLoginMethods: LoginMethod[] = [
28
30
  { id: 'password', name: '密码登录', icon: 'pwd' },
31
+ { id: 'web', name: '网页登录', icon: 'web' },
29
32
  { id: 'wechat', name: '微信登录', icon: 'wxmpSvg', appid: "wx9378885c8390e09b" },
30
33
  { id: 'wechat-mp', name: '微信公众号', icon: 'wxOpenSvg', appid: WX_MP_APP_ID },
31
34
  { id: 'wechat-mp-ticket', name: '微信公众号', icon: 'wxOpenSvg' },
32
35
  { id: 'phone', name: '手机号登录', icon: 'phone' }
33
36
  ]
34
- const LoginMethods = ['password', 'phone', 'wechat', 'wechat-mp', 'wechat-mp-ticket'] as const;
35
- type LoginMethods = 'password' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket';
37
+ const LoginMethods = ['password', 'web', 'phone', 'wechat', 'wechat-mp', 'wechat-mp-ticket'] as const;
38
+ type LoginMethods = 'password' | 'web' | 'phone' | 'wechat' | 'wechat-mp' | 'wechat-mp-ticket';
36
39
 
37
40
  const getLoginMethodByDomain = (): LoginMethod[] => {
38
41
  let domain = window.location.host
39
42
  let methods: LoginMethods[] = []
40
- const has51015 = domain.includes('51015');
41
- if (has51015) {
42
- domain = 'localhost:51015'
43
+ const has51 = domain.includes('localhost') && (domain.endsWith('51515') || domain.endsWith('51015'));
44
+ if (has51) {
45
+ domain = 'localhost'
43
46
  }
44
47
  switch (domain) {
45
48
  case 'kevisual.xiongxiao.me':
@@ -48,11 +51,11 @@ const getLoginMethodByDomain = (): LoginMethod[] => {
48
51
  case 'kevisual.cn':
49
52
  methods = ['password', 'wechat-mp-ticket', 'wechat',]
50
53
  break;
51
- case 'localhost:51015':
52
- methods = ['password']
54
+ case 'localhost':
55
+ methods = ['password', 'web']
53
56
  break
54
57
  default:
55
- methods = ['password', 'phone', 'wechat', 'wechat-mp', 'wechat-mp-ticket']
58
+ methods = ['password', 'web', 'phone', 'wechat', 'wechat-mp', 'wechat-mp-ticket']
56
59
  break;
57
60
  }
58
61
  return DefaultLoginMethods.filter(method => methods.includes(method.id))
@@ -161,7 +164,8 @@ class KvLogin extends HTMLElement {
161
164
  username: username?.value || '',
162
165
  password: password?.value || ''
163
166
  }
164
-
167
+ case 'web':
168
+ return {}
165
169
  case 'phone':
166
170
  const phone = this.shadowRoot.querySelector('#phone') as HTMLInputElement
167
171
  const code = this.shadowRoot.querySelector('#code') as HTMLInputElement
@@ -210,7 +214,14 @@ class KvLogin extends HTMLElement {
210
214
  </form>
211
215
  `
212
216
  }
213
-
217
+ private renderWebForm() {
218
+ return html`
219
+ <div class="web-login">
220
+ <button type="button" class="refresh-button" @click=${this.handleLogin.bind(this)}>点击登录</button>
221
+ <slot></slot>
222
+ </div>
223
+ `
224
+ }
214
225
  private renderPhoneForm() {
215
226
  return html`
216
227
  <form id="loginForm" class="login-form">
@@ -308,6 +319,8 @@ class KvLogin extends HTMLElement {
308
319
  switch (this.selectedMethod) {
309
320
  case 'password':
310
321
  return this.renderPasswordForm()
322
+ case 'web':
323
+ return this.renderWebForm()
311
324
  case 'phone':
312
325
  return this.renderPhoneForm()
313
326
  case 'wechat':