@kengcom202/kcore-ui 0.4.0 → 0.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kengcom202/kcore-ui",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Angular UI กลาง: ช่องเลือกวันที่แบบ พ.ศ., ช่องเลือกเวลาแบบหน้าปัด, dropdown ค้นหาได้, ตัวแก้ข้อความไทยที่คัดลอกจาก PDF และชุดหน้าเข้าสู่ระบบ/ลงทะเบียน/ข้อมูลส่วนตัว/config (ไม่พึ่งไลบรารีภายนอก)",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -1,8 +1,8 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { AfterContentInit, ApplicationRef, ElementRef, EnvironmentInjector, EnvironmentProviders, InjectionToken, NgZone, OnDestroy, OnInit, Type } from "@angular/core";
3
3
  import { ControlValueAccessor } from "@angular/forms";
4
- import { HttpInterceptorFn } from "@angular/common/http";
5
- import { CanActivateFn, Routes } from "@angular/router";
4
+ import { HttpClient, HttpInterceptorFn } from "@angular/common/http";
5
+ import { CanActivateFn, Router, Routes } from "@angular/router";
6
6
  /**
7
7
  * ช่องเลือกวันที่แบบไทย ใช้กับ <input type="text" appDatePicker formControlName="...">
8
8
  * - ค่าใน form control เป็น ค.ศ. yyyy-MM-dd เสมอ (ตรงกับที่ API ใช้) ส่วนในช่องแสดงเป็น พ.ศ.
@@ -324,6 +324,8 @@ export declare function fixThaiText(text: string): string;
324
324
  * ผ่าน execCommand('insertText') เพื่อให้ ngModel / formControl ได้ event input และ Ctrl+Z ย้อนได้
325
325
  */
326
326
  export declare function provideThaiPasteFix(): EnvironmentProviders;
327
+ /** โหมดลงทะเบียนผู้ใช้ใหม่ — ดู KcAuthOptions.register */
328
+ export type KcRegisterMode = 'none' | 'form' | 'sso' | 'thaid';
327
329
  /** ค่าที่โปรเจกต์ส่งให้ provideKcAuth() — ทุกค่ายกเว้น appName มีค่าเริ่มต้น */
328
330
  export interface KcAuthOptions {
329
331
  /** ชื่อระบบ แสดงบนหน้าเข้าสู่ระบบ/ลงทะเบียน */
@@ -339,8 +341,15 @@ export interface KcAuthOptions {
339
341
  label?: string;
340
342
  };
341
343
  /**
342
- * เข้าสู่ระบบด้วยชื่อผู้ใช้/รหัสผ่าน ค่าเริ่มต้น true — false = หน้าเข้าสู่ระบบมีแต่ปุ่ม SSO ตรงกลาง
343
- * (มีผลเฉพาะเมื่อเปิด sso ไว้ ถ้าปิดทั้งคู่จะยังแสดงช่องรหัสผ่าน กันไม่ให้ไม่มีทางเข้าระบบ)
344
+ * เปิดปุ่ม ThaiD (แอปยืนยันตัวตนของกรมการปกครอง) — เข้าสู่ระบบอย่างเดียว ไม่ใช้ลงทะเบียน (ยกเว้น register: 'thaid')
345
+ * API จับคู่เลขบัตรประชาชนกับบัญชีที่มีอยู่แล้ว ไม่พบ = แจ้งให้ติดต่อผู้ดูแล; label ค่าเริ่มต้น 'ThaiD'; false/ไม่ใส่ = ปิด
346
+ */
347
+ thaid?: false | {
348
+ label?: string;
349
+ };
350
+ /**
351
+ * เข้าสู่ระบบด้วยชื่อผู้ใช้/รหัสผ่าน ค่าเริ่มต้น true — false = หน้าเข้าสู่ระบบมีแต่ปุ่ม SSO / ThaiD ตรงกลาง
352
+ * (มีผลเฉพาะเมื่อเปิด sso หรือ thaid ไว้ ถ้าปิดหมดจะยังแสดงช่องรหัสผ่าน กันไม่ให้ไม่มีทางเข้าระบบ)
344
353
  */
345
354
  passwordLogin?: boolean;
346
355
  /**
@@ -348,8 +357,16 @@ export interface KcAuthOptions {
348
357
  * 'none' — ไม่เปิดให้สมัครเอง (ผู้ดูแลเพิ่มให้) — ค่าเริ่มต้น
349
358
  * 'form' — กรอกฟอร์มเองที่ /register
350
359
  * 'sso' — ยืนยันตัวตนผ่าน SSO ก่อน แล้ว API ส่งตั๋วลงทะเบียนมาให้กรอกต่อที่ /register
360
+ * 'thaid' — ยืนยันตัวตนผ่าน ThaiD ก่อน แล้ว API ส่งตั๋วลงทะเบียนมาให้กรอกต่อที่ /register (ต้องเปิด thaid)
361
+ * สำหรับระบบที่เป็นหลังบ้านของ SSO เท่านั้น — SSO ไม่พบบัญชีตอบ { mode: 'thaid' } ส่งต่อไป ThaiD ได้
351
362
  */
352
- register?: 'none' | 'form' | 'sso';
363
+ register?: KcRegisterMode;
364
+ /**
365
+ * ให้ผู้ใช้ขอย้ายหน่วยงานเองที่หน้าบัญชีของฉัน ค่าเริ่มต้น false (ย้ายได้โดยผู้ดูแลที่หน้า config เท่านั้น)
366
+ * true = แสดงช่องเลือกหน่วยงานเมื่อ GET {api}/user/me ส่ง orgs มา แล้วส่ง org ไปกับ PUT {api}/user/me
367
+ * (API ตัดสินเองว่าย้ายทันทีหรือรออนุมัติ แล้วตอบ { message })
368
+ */
369
+ profileOrgChange?: boolean;
353
370
  /** ชื่อเรียกหน่วยงานที่สังกัด เช่น 'หน่วยงาน', 'โรงพยาบาล', 'แผนก' ค่าเริ่มต้น 'หน่วยงาน' */
354
371
  orgLabel?: string;
355
372
  /** ค่า role ที่ถือว่าเป็นผู้ดูแล (เข้า kcAdminGuard ได้) ค่าเริ่มต้น ['admin'] */
@@ -368,8 +385,12 @@ export interface KcAuthConfig {
368
385
  sso: {
369
386
  label: string;
370
387
  } | null;
388
+ thaid: {
389
+ label: string;
390
+ } | null;
371
391
  passwordLogin: boolean;
372
- register: 'none' | 'form' | 'sso';
392
+ register: KcRegisterMode;
393
+ profileOrgChange: boolean;
373
394
  orgLabel: string;
374
395
  adminRoles: string[];
375
396
  passwordMinLength: number;
@@ -381,13 +402,14 @@ export declare const KC_AUTH_PATHS: {
381
402
  readonly login: "/login";
382
403
  readonly register: "/register";
383
404
  readonly ssoCallback: "/sso-callback";
405
+ readonly thaidCallback: "/thaid-callback";
384
406
  };
385
407
  export declare function resolveKcAuthConfig(o: KcAuthOptions): KcAuthConfig;
386
408
  /**
387
409
  * ตั้งค่าชุดหน้าบัญชีผู้ใช้ — ใส่ใน app.config.ts ครั้งเดียว คู่กับ kcAuthInterceptor
388
410
  * providers: [
389
411
  * provideHttpClient(withInterceptors([kcAuthInterceptor])),
390
- * provideKcAuth({ appName: 'ระบบ...', sso: { label: 'DMS SSO' }, register: 'sso' }),
412
+ * provideKcAuth({ appName: 'ระบบ...', sso: { label: 'DMS SSO' }, thaid: {}, register: 'sso' }),
391
413
  * ]
392
414
  */
393
415
  export declare function provideKcAuth(options: KcAuthOptions): EnvironmentProviders;
@@ -405,17 +427,51 @@ export interface KcSession {
405
427
  token: string;
406
428
  user: KcUser;
407
429
  }
408
- /** GET {api}/user/sso/authorize-url */
430
+ /**
431
+ * POST {api}/user/login ตอบ 429 เมื่อรหัสผ่านผิดครบ 3 ครั้ง (นับต่อชื่อผู้ใช้) — ต้องรอ retryAfter วินาที (5 นาทีนับจากครั้งที่ 3)
432
+ * ระหว่างล็อก API ไม่ตรวจรหัสผ่าน (ถูกก็ตอบ 429) และเข้าสู่ระบบสำเร็จ = ล้างตัวนับ
433
+ */
434
+ export interface KcLoginLocked {
435
+ message: string;
436
+ retryAfter: number;
437
+ }
438
+ /** ไม่มี retryAfter ใน 429 = ถือว่ารอ 5 นาที */
439
+ export declare const KC_LOGIN_LOCK_SECONDS = 300;
440
+ /** วินาทีที่ต้องรอจาก 429 ของ user/login — คำตอบอื่น = 0 */
441
+ export declare function kcLoginRetryAfter(err: unknown): number;
442
+ /** GET {api}/user/sso/authorize-url และ GET {api}/user/thaid/authorize-url */
409
443
  export interface KcSsoAuthorize {
410
444
  url: string;
411
445
  state: string;
412
446
  }
413
- /** POST {api}/user/sso/callback { code } */
447
+ /**
448
+ * GET {api}/user/login-methods (ไม่ต้องเข้าสู่ระบบ) และ PUT {api}/config/login-methods (ผู้ดูแล)
449
+ * วิธีเข้าสู่ระบบที่ผู้ดูแลเปิดไว้ — ต้องเปิดอย่างน้อย 1 วิธี (API ต้องปฏิเสธเมื่อปิดหมด)
450
+ */
451
+ export interface KcLoginMethods {
452
+ password: boolean;
453
+ sso: boolean;
454
+ thaid: boolean;
455
+ }
456
+ /**
457
+ * POST {api}/user/sso/callback { code }
458
+ * thaid — ไม่พบบัญชี ให้ยืนยันตัวตนด้วย ThaiD ต่อ (ใช้ได้เฉพาะ register: 'thaid')
459
+ */
414
460
  export type KcSsoCallbackResult = ({
415
461
  mode: 'signed-in';
416
462
  } & KcSession) | {
417
463
  mode: 'register';
418
464
  ticket: string;
465
+ } | {
466
+ mode: 'thaid';
467
+ };
468
+ /**
469
+ * POST {api}/user/thaid/callback { code } — พบบัญชี = KcSession
470
+ * ไม่พบบัญชี: ปกติ 403 { message }; register: 'thaid' ตอบตั๋วลงทะเบียนแทนได้
471
+ */
472
+ export type KcThaidCallbackResult = KcSession | {
473
+ mode: 'register';
474
+ ticket: string;
419
475
  };
420
476
  /** GET {api}/user/register-info[?ticket=] — ตั๋วจาก SSO ทำให้ได้ชื่อ-สกุล (และหน่วยงาน) ที่ยืนยันแล้ว */
421
477
  export interface KcRegisterInfo {
@@ -453,6 +509,8 @@ export interface KcProfile {
453
509
  orgName: string;
454
510
  email: string;
455
511
  mobile: string;
512
+ /** หน่วยงานที่ขอย้ายไปได้ — ใช้เมื่อ profileOrgChange: true (ไม่ส่ง/ว่าง = แสดงหน่วยงานแบบอ่านอย่างเดียว) */
513
+ orgs?: SearchOption[];
456
514
  }
457
515
  /** PUT {api}/user/me — password ว่าง = ไม่เปลี่ยน */
458
516
  export interface KcProfileUpdate {
@@ -460,6 +518,8 @@ export interface KcProfileUpdate {
460
518
  email: string;
461
519
  mobile: string;
462
520
  password: string;
521
+ /** ส่งเฉพาะเมื่อ profileOrgChange: true และ GET user/me ส่ง orgs มา */
522
+ org?: string;
463
523
  }
464
524
  /** แถวในหน้า config ผู้ใช้ */
465
525
  export interface KcConfigUser {
@@ -518,6 +578,7 @@ export interface KcMessage {
518
578
  export declare function kcErrorMessage(err: unknown, fallback: string): string;
519
579
  export declare const KC_SSO_STATE_KEY = "kc_sso_state";
520
580
  export declare const KC_SSO_TICKET_KEY = "kc_sso_ticket";
581
+ export declare const KC_THAID_STATE_KEY = "kc_thaid_state";
521
582
  export declare const KC_RETURN_URL_KEY = "kc_return_url";
522
583
  /** token เป็น JWT ที่มี exp และเลยเวลาแล้ว — token รูปแบบอื่นถือว่ายังไม่หมดอายุ (ให้ API ตัดสินด้วย 401) */
523
584
  export declare function kcTokenExpired(token: string, now?: number): boolean;
@@ -578,7 +639,7 @@ export declare const kcAuthInterceptor: HttpInterceptorFn;
578
639
  * { path: 'config/kcllu', component: KcConfigKclluComponent, canActivate: [kcAdminGuard] },
579
640
  * ] },
580
641
  * ];
581
- * path ตรงกับ KC_AUTH_PATHS (login, register, sso-callback)
642
+ * path ตรงกับ KC_AUTH_PATHS (login, register, sso-callback, thaid-callback)
582
643
  */
583
644
  export declare function kcAuthRoutes(): Routes;
584
645
  /**
@@ -596,10 +657,14 @@ export declare class KcPasswordToggleComponent implements AfterContentInit {
596
657
  static ɵfac: i0.ɵɵFactoryDeclaration<KcPasswordToggleComponent, never>;
597
658
  static ɵcmp: i0.ɵɵComponentDeclaration<KcPasswordToggleComponent, "kc-password", never, {}, {}, never, ["*"], true, never>;
598
659
  }
660
+ /** เวลาปลดล็อกของแต่ละชื่อผู้ใช้หลังได้ 429 จาก user/login */
661
+ export declare const KC_LOGIN_LOCK_KEY = "kc_login_lock";
599
662
  /**
600
663
  * หน้าเข้าสู่ระบบ (route /login จาก kcAuthRoutes())
601
- * ชื่อผู้ใช้/รหัสผ่าน → POST {api}/user/login → KcSession
664
+ * ชื่อผู้ใช้/รหัสผ่าน → POST {api}/user/login → KcSession (ผิดครบ 3 ครั้ง API ตอบ 429 → นับถอยหลังตาม retryAfter และปิดปุ่ม)
602
665
  * ปุ่ม SSO (ถ้าเปิด) → GET {api}/user/sso/authorize-url → ไปหน้า SSO แล้วกลับมาที่ /sso-callback
666
+ * ปุ่ม ThaiD (ถ้าเปิด) → GET {api}/user/thaid/authorize-url → ไปหน้า ThaiD แล้วกลับมาที่ /thaid-callback (ลงทะเบียนเฉพาะ register: 'thaid')
667
+ * วิธีที่แสดงตาม GET {api}/user/login-methods (ผู้ดูแลเปิด/ปิดที่หน้า config ผู้ใช้) — ไม่มี endpoint = ตาม provideKcAuth
603
668
  * query: returnUrl = หน้าที่จะกลับไปหลังเข้าสู่ระบบ, expired=1 = แจ้งหมดเวลาการใช้งาน
604
669
  * เนื้อหาที่ใส่ไว้ใน <kc-login>...</kc-login> แสดงท้ายการ์ด (เช่นเบอร์ติดต่อผู้ดูแล)
605
670
  */
@@ -609,12 +674,31 @@ export declare class KcLoginComponent implements OnInit {
609
674
  readonly login: "/login";
610
675
  readonly register: "/register";
611
676
  readonly ssoCallback: "/sso-callback";
677
+ readonly thaidCallback: "/thaid-callback";
612
678
  };
613
679
  private readonly auth;
614
680
  private readonly http;
615
681
  private readonly router;
616
682
  private readonly route;
617
- protected readonly busy: import("@angular/core").WritableSignal<"" | "sso" | "password">;
683
+ private readonly doc;
684
+ protected readonly busy: import("@angular/core").WritableSignal<"" | "sso" | "thaid" | "password">;
685
+ /**
686
+ * วิธีที่ผู้ดูแลเปิดไว้ (GET {api}/user/login-methods) — ก่อนได้คำตอบ หรือ API ยังไม่มี endpoint นี้ ใช้ค่าจาก provideKcAuth
687
+ * แต่ละวิธีแสดงเมื่อทั้ง provideKcAuth เปิดไว้ (passwordLogin / sso / thaid) และผู้ดูแลเปิด
688
+ */
689
+ protected readonly methods: import("@angular/core").WritableSignal<KcLoginMethods>;
690
+ /** ปุ่มเข้าสู่ระบบภายนอกที่เปิดไว้ เรียง SSO ก่อน ThaiD */
691
+ protected readonly external: import("@angular/core").Signal<({
692
+ key: "sso";
693
+ label: string;
694
+ stateKey: string;
695
+ } | {
696
+ key: "thaid";
697
+ label: string;
698
+ stateKey: string;
699
+ })[]>;
700
+ /** ไม่เหลือปุ่มภายนอกเลย = แสดงช่องรหัสผ่านเสมอ กันไม่ให้ไม่มีทางเข้าระบบ */
701
+ protected readonly showPassword: import("@angular/core").Signal<boolean>;
618
702
  protected readonly message: import("@angular/core").WritableSignal<{
619
703
  text: string;
620
704
  error: boolean;
@@ -623,11 +707,27 @@ export declare class KcLoginComponent implements OnInit {
623
707
  username: import("@angular/forms").FormControl<string>;
624
708
  password: import("@angular/forms").FormControl<string>;
625
709
  }>;
710
+ /**
711
+ * ชื่อผู้ใช้ที่ถูกล็อก → เวลาปลดล็อก (ms) — เก็บใน localStorage ให้รีเฟรชแล้วยังนับต่อ
712
+ * API เป็นผู้ล็อกจริง ส่วนนี้แค่แสดงเวลานับถอยหลังและกันกดซ้ำ — พิมพ์ชื่อผู้ใช้อื่นกดได้ตามปกติ
713
+ */
714
+ private readonly locks;
715
+ private readonly now;
716
+ private readonly username;
717
+ /** วินาทีที่ยังต้องรอของชื่อผู้ใช้ในช่อง (0 = ไม่ล็อก) */
718
+ protected readonly lockLeft: import("@angular/core").Signal<number>;
719
+ protected readonly lockText: import("@angular/core").Signal<string>;
720
+ private timer;
626
721
  constructor();
627
722
  private get returnUrl();
628
723
  ngOnInit(): void;
629
724
  protected submit(): void;
630
- protected startSso(): void;
725
+ /** until = 0 คือปลดล็อก */
726
+ private setLock;
727
+ private startTimer;
728
+ private stopTimer;
729
+ private storage;
730
+ protected startExternal(key: 'sso' | 'thaid'): void;
631
731
  static ɵfac: i0.ɵɵFactoryDeclaration<KcLoginComponent, never>;
632
732
  static ɵcmp: i0.ɵɵComponentDeclaration<KcLoginComponent, "kc-login", never, {}, {}, never, ["*"], true, never>;
633
733
  }
@@ -635,6 +735,7 @@ export declare class KcLoginComponent implements OnInit {
635
735
  * หน้าลงทะเบียนผู้ใช้ใหม่ (route /register) — รูปแบบตาม ictprocure: กล่องเดียว ช่องเรียงแถวเดียว
636
736
  * ทำงานตาม register ใน provideKcAuth()
637
737
  * 'sso' — ต้องมาจาก /sso-callback พร้อมตั๋ว ชื่อ-สกุล / เลขบัตรประชาชน (และหน่วยงานถ้า orgLocked) มาจาก API แก้ไม่ได้
738
+ * 'thaid' — เหมือน 'sso' แต่ตั๋วมาจาก /thaid-callback
638
739
  * 'form' — กรอกชื่อ-สกุลเอง
639
740
  * 'none' — แจ้งว่าไม่เปิดให้ลงทะเบียน
640
741
  * อีเมล / มือถือไม่ถามตอนลงทะเบียน — ผู้ใช้กรอกต่อที่หน้าบัญชีของฉัน
@@ -646,7 +747,9 @@ export declare class KcRegisterComponent implements OnInit {
646
747
  readonly login: "/login";
647
748
  readonly register: "/register";
648
749
  readonly ssoCallback: "/sso-callback";
750
+ readonly thaidCallback: "/thaid-callback";
649
751
  };
752
+ /** ผู้ยืนยันตัวตนของตั๋วลงทะเบียน — แสดงใน "(จาก ...)" และข้อความเมื่อยังไม่มีตั๋ว */
650
753
  protected readonly ssoLabel: string;
651
754
  private readonly auth;
652
755
  private readonly http;
@@ -679,38 +782,74 @@ export declare class KcRegisterComponent implements OnInit {
679
782
  static ɵfac: i0.ɵɵFactoryDeclaration<KcRegisterComponent, never>;
680
783
  static ɵcmp: i0.ɵɵComponentDeclaration<KcRegisterComponent, "kc-register", never, {}, {}, never, never, true, never>;
681
784
  }
682
- /**
683
- * หน้ารับ redirect กลับจาก SSO (route /sso-callback) — path นี้ต้องตรงกับ redirect_uri ที่ API ส่งให้ SSO
684
- * และที่ลงทะเบียนไว้กับ SSO server
685
- * ?code=&state= → ตรวจ state → POST {api}/user/sso/callback { code }
686
- * signed-in → เริ่ม session แล้วกลับหน้าเดิม / homeUrl
687
- * register → เก็บตั๋วไว้ใน sessionStorage แล้วไป /register
688
- * ไม่มี code (เช่นเปิดจากเมนูของ SSO portal) → เริ่ม flow ใหม่เอง
689
- */
690
- export declare class KcSsoCallbackComponent implements OnInit {
691
- private readonly config;
692
- private readonly auth;
693
- private readonly http;
785
+ /** ส่วนที่หน้า callback ของ SSO และ ThaiD ใช้ร่วมกัน — ต่างกันที่ endpoint, คีย์ state และผลของ callback */
786
+ declare abstract class KcExternalCallbackBase implements OnInit {
787
+ protected readonly config: import("@kengcom202/kcore-ui").KcAuthConfig;
788
+ protected readonly auth: KcAuthService;
789
+ protected readonly http: HttpClient;
790
+ protected readonly router: Router;
694
791
  private readonly route;
695
- private readonly router;
696
792
  protected readonly paths: {
697
793
  readonly login: "/login";
698
794
  readonly register: "/register";
699
795
  readonly ssoCallback: "/sso-callback";
796
+ readonly thaidCallback: "/thaid-callback";
700
797
  };
701
- protected readonly label: string;
798
+ protected abstract readonly label: string;
799
+ /** path ใต้ {api}/user/ เช่น 'sso' → {api}/user/sso/authorize-url, {api}/user/sso/callback */
800
+ protected abstract readonly endpoint: string;
801
+ protected abstract readonly stateKey: string;
702
802
  protected readonly message: import("@angular/core").WritableSignal<string>;
703
803
  protected readonly failed: import("@angular/core").WritableSignal<boolean>;
704
804
  constructor();
805
+ /** แลก code แล้วจัดการผล */
806
+ protected abstract exchange(code: string): void;
705
807
  ngOnInit(): void;
706
- private fail;
808
+ /** ขอ url ของผู้ให้บริการ เก็บ state แล้วพาไปหน้านั้น */
809
+ protected startFlow(endpoint: string, stateKey: string, label: string): void;
810
+ /** เก็บตั๋วลงทะเบียนแล้วไปหน้า /register (ตั๋วจาก SSO และ ThaiD ใช้คีย์เดียวกัน) */
811
+ protected toRegister(ticket: string): void;
812
+ protected signIn(session: KcSession): void;
813
+ protected fail(message: string): void;
814
+ static ɵfac: i0.ɵɵFactoryDeclaration<KcExternalCallbackBase, never>;
815
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KcExternalCallbackBase, never, never, {}, {}, never, never, true, never>;
816
+ }
817
+ /**
818
+ * หน้ารับ redirect กลับจาก SSO (route /sso-callback) — path นี้ต้องตรงกับ redirect_uri ที่ API ส่งให้ SSO
819
+ * และที่ลงทะเบียนไว้กับ SSO server
820
+ * ?code=&state= → ตรวจ state → POST {api}/user/sso/callback { code }
821
+ * signed-in → เริ่ม session แล้วกลับหน้าเดิม / homeUrl
822
+ * register → เก็บตั๋วไว้ใน sessionStorage แล้วไป /register
823
+ * thaid → (register: 'thaid') ไม่พบบัญชี ส่งต่อไปยืนยันตัวตนด้วย ThaiD
824
+ * ไม่มี code (เช่นเปิดจากเมนูของ SSO portal) → เริ่ม flow ใหม่เอง
825
+ */
826
+ export declare class KcSsoCallbackComponent extends KcExternalCallbackBase {
827
+ protected readonly label: string;
828
+ protected readonly endpoint = "sso";
829
+ protected readonly stateKey = "kc_sso_state";
830
+ protected exchange(code: string): void;
707
831
  static ɵfac: i0.ɵɵFactoryDeclaration<KcSsoCallbackComponent, never>;
708
832
  static ɵcmp: i0.ɵɵComponentDeclaration<KcSsoCallbackComponent, "kc-sso-callback", never, {}, {}, never, never, true, never>;
709
833
  }
834
+ /**
835
+ * หน้ารับ redirect กลับจาก ThaiD (route /thaid-callback) — เข้าสู่ระบบอย่างเดียว ไม่มีการลงทะเบียน
836
+ * ?code=&state= → ตรวจ state → POST {api}/user/thaid/callback { code } → KcSession
837
+ * API ไม่พบบัญชีที่ผูกกับเลขบัตรประชาชน = ตอบ 403 { message } แสดงข้อความนั้น (ให้ติดต่อผู้ดูแล)
838
+ * ยกเว้น register: 'thaid' — API ตอบ { mode: 'register', ticket } ได้ → เก็บตั๋วแล้วไป /register
839
+ */
840
+ export declare class KcThaidCallbackComponent extends KcExternalCallbackBase {
841
+ protected readonly label: string;
842
+ protected readonly endpoint = "thaid";
843
+ protected readonly stateKey = "kc_thaid_state";
844
+ protected exchange(code: string): void;
845
+ static ɵfac: i0.ɵɵFactoryDeclaration<KcThaidCallbackComponent, never>;
846
+ static ɵcmp: i0.ɵɵComponentDeclaration<KcThaidCallbackComponent, "kc-thaid-callback", never, {}, {}, never, never, true, never>;
847
+ }
710
848
  /**
711
849
  * หน้า "บัญชีของฉัน" (user/detail) — รูปแบบตาม ictprocure: กล่องเดียวกลางหน้า ช่องเรียงแถวเดียว
712
850
  * วางใน layout ของโปรเจกต์พร้อม canActivate: [kcAuthGuard]
713
851
  * ชื่อ-สกุลและหน่วยงานแสดงอย่างเดียว (หน่วยงานกำหนดสิทธิ์การเห็นข้อมูล ย้ายได้โดยผู้ดูแลที่หน้า config)
852
+ * ยกเว้น profileOrgChange: true และ API ส่ง orgs มา — เลือกหน่วยงานได้ ส่ง org ไปกับ PUT (API ตัดสินว่ารออนุมัติไหม)
714
853
  * แก้ได้: อีเมล มือถือ ชื่อผู้ใช้ รหัสผ่าน — เปลี่ยนรหัสผ่านไม่ต้องกรอกรหัสเดิม เว้นว่าง = ไม่เปลี่ยน
715
854
  * GET {api}/user/me → KcProfile, PUT {api}/user/me ← KcProfileUpdate
716
855
  */
@@ -726,10 +865,13 @@ export declare class KcProfileComponent implements OnInit {
726
865
  protected readonly success: import("@angular/core").WritableSignal<string>;
727
866
  protected readonly fullName: import("@angular/core").WritableSignal<string>;
728
867
  protected readonly orgName: import("@angular/core").WritableSignal<string>;
868
+ /** หน่วยงานที่เลือกย้ายได้ — ว่าง = แสดงแบบอ่านอย่างเดียว */
869
+ protected readonly orgs: import("@angular/core").WritableSignal<SearchOption[]>;
729
870
  protected readonly form: import("@angular/forms").FormGroup<{
730
871
  email: import("@angular/forms").FormControl<string>;
731
872
  mobile: import("@angular/forms").FormControl<string>;
732
873
  username: import("@angular/forms").FormControl<string>;
874
+ org: import("@angular/forms").FormControl<string>;
733
875
  password: import("@angular/forms").FormControl<string>;
734
876
  confirmPassword: import("@angular/forms").FormControl<string>;
735
877
  }>;
@@ -751,6 +893,8 @@ interface UserEdit extends KcConfigUserUpdate {
751
893
  * ค้นหา แล้วคลิกแถวเพื่อแก้ ชื่อผู้ใช้ / ระดับผู้ใช้ / สถานะ / หน่วยงาน / ตั้งรหัสผ่านใหม่
752
894
  * ไม่มีการลบ — ใช้ "ระงับการใช้งาน" แทน และแก้ระดับ/สถานะของตัวเองไม่ได้ (กันผู้ดูแลล็อกตัวเองออก)
753
895
  * GET {api}/config/users → { users, orgs, roles }, PUT {api}/config/users/{id} ← KcConfigUserUpdate
896
+ * ส่วนบน: เปิด/ปิดวิธีเข้าสู่ระบบ (รหัสผ่าน / SSO / ThaiD ที่ provideKcAuth เปิดไว้) ห้ามปิดหมด
897
+ * GET {api}/user/login-methods → KcLoginMethods, PUT {api}/config/login-methods ← KcLoginMethods (ไม่มี endpoint = ซ่อนส่วนนี้)
754
898
  */
755
899
  export declare class KcConfigUsersComponent implements OnInit {
756
900
  protected readonly config: import("@kengcom202/kcore-ui").KcAuthConfig;
@@ -767,11 +911,31 @@ export declare class KcConfigUsersComponent implements OnInit {
767
911
  protected readonly search: import("@angular/core").WritableSignal<string>;
768
912
  protected readonly editing: import("@angular/core").WritableSignal<UserEdit | null>;
769
913
  protected readonly myId: import("@angular/core").Signal<string>;
914
+ /** วิธีเข้าสู่ระบบ: ค่าที่บันทึกแล้ว / ค่าที่กำลังแก้ (null = API ไม่มี endpoint หรือโหลดไม่ได้ → ซ่อนส่วนนี้) */
915
+ private readonly methodsSaved;
916
+ protected readonly methodsDraft: import("@angular/core").WritableSignal<KcLoginMethods | null>;
917
+ protected readonly savingMethods: import("@angular/core").WritableSignal<boolean>;
918
+ protected readonly methodsError: import("@angular/core").WritableSignal<string>;
919
+ /** เฉพาะวิธีที่ provideKcAuth เปิดไว้ — วิธีที่หน้าเว็บไม่มีปุ่มให้ไม่นับ */
920
+ protected readonly methodOptions: import("@angular/core").Signal<({
921
+ key: "password";
922
+ label: string;
923
+ } | {
924
+ key: "sso";
925
+ label: string;
926
+ } | {
927
+ key: "thaid";
928
+ label: string;
929
+ })[]>;
930
+ protected readonly enabledCount: import("@angular/core").Signal<number>;
931
+ protected readonly methodsDirty: import("@angular/core").Signal<boolean>;
770
932
  /** ตัวเลือกหน่วยงานในป็อปอัป — มี "ไม่ระบุ" ไว้ล้างค่า */
771
933
  protected readonly orgOptions: import("@angular/core").Signal<SearchOption[]>;
772
934
  protected readonly filtered: import("@angular/core").Signal<KcConfigUser[]>;
773
935
  constructor();
774
936
  ngOnInit(): void;
937
+ protected toggleMethod(key: keyof KcLoginMethods, on: boolean): void;
938
+ protected saveMethods(): void;
775
939
  protected load(): void;
776
940
  protected roleName(role: string): string;
777
941
  protected hasRole(role: string): boolean;