@spfn/auth 0.2.1 → 0.3.0-beta.1
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/LICENSE +1 -1
- package/README.md +1032 -2397
- package/dist/{authenticate-eucncHxN.d.ts → authenticate-DlTGaBT8.d.ts} +545 -82
- package/dist/client-proof.d.ts +606 -0
- package/dist/client-proof.js +1842 -0
- package/dist/client-proof.js.map +1 -0
- package/dist/config.d.ts +319 -3
- package/dist/config.js +155 -5
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +180 -3
- package/dist/errors.js +116 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +122 -18
- package/dist/index.js +129 -8
- package/dist/index.js.map +1 -1
- package/dist/nextjs/api.js +404 -96
- package/dist/nextjs/api.js.map +1 -1
- package/dist/nextjs/server.d.ts +5 -4
- package/dist/nextjs/server.js +165 -26
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +2130 -1016
- package/dist/server.js +4916 -739
- package/dist/server.js.map +1 -1
- package/dist/session-DTHahDQ9.d.ts +53 -0
- package/dist/types-DYyhze28.d.ts +98 -0
- package/dist/wire-version-CtzMKvBB.d.ts +134 -0
- package/migrations/20251125021229_premium_famine/snapshot.json +2641 -0
- package/migrations/20260225130050_smooth_the_fury/snapshot.json +2686 -0
- package/migrations/20260308141417_deep_iceman/snapshot.json +2686 -0
- package/migrations/20260308151309_perfect_deathbird/snapshot.json +2731 -0
- package/migrations/20260308201135_concerned_rawhide_kid/snapshot.json +2786 -0
- package/migrations/20260629103209_lethal_lifeguard/migration.sql +32 -0
- package/migrations/20260629103209_lethal_lifeguard/snapshot.json +2786 -0
- package/migrations/20260709073531_easy_hardball/migration.sql +24 -0
- package/migrations/20260709073531_easy_hardball/snapshot.json +3119 -0
- package/migrations/20260714081434_glossy_major_mapleleaf/migration.sql +1 -0
- package/migrations/20260714081434_glossy_major_mapleleaf/snapshot.json +3112 -0
- package/migrations/20260804105939_amazing_bushwacker/migration.sql +3 -0
- package/migrations/20260804105939_amazing_bushwacker/snapshot.json +3112 -0
- package/migrations/20260804110033_fat_piledriver/migration.sql +2 -0
- package/migrations/20260804110033_fat_piledriver/snapshot.json +3138 -0
- package/migrations/20260805143152_vengeful_ravenous/migration.sql +4 -0
- package/migrations/20260805143152_vengeful_ravenous/snapshot.json +3190 -0
- package/package.json +54 -40
- package/migrations/meta/0000_snapshot.json +0 -1632
- package/migrations/meta/0001_snapshot.json +0 -1660
- package/migrations/meta/0002_snapshot.json +0 -1660
- package/migrations/meta/0003_snapshot.json +0 -1689
- package/migrations/meta/0004_snapshot.json +0 -1721
- package/migrations/meta/_journal.json +0 -41
- /package/migrations/{0000_premium_famine.sql → 20251125021229_premium_famine/migration.sql} +0 -0
- /package/migrations/{0001_smooth_the_fury.sql → 20260225130050_smooth_the_fury/migration.sql} +0 -0
- /package/migrations/{0002_deep_iceman.sql → 20260308141417_deep_iceman/migration.sql} +0 -0
- /package/migrations/{0003_perfect_deathbird.sql → 20260308151309_perfect_deathbird/migration.sql} +0 -0
- /package/migrations/{0004_concerned_rawhide_kid.sql → 20260308201135_concerned_rawhide_kid/migration.sql} +0 -0
package/dist/config.d.ts
CHANGED
|
@@ -19,11 +19,11 @@ import * as _spfn_core_env from '@spfn/core/env';
|
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
21
|
* ```typescript
|
|
22
|
-
* import {
|
|
22
|
+
* import { envSchema } from '@spfn/auth/config';
|
|
23
23
|
*
|
|
24
24
|
* // Access schema information
|
|
25
|
-
* console.log(
|
|
26
|
-
* console.log(
|
|
25
|
+
* console.log(envSchema.SPFN_AUTH_SESSION_SECRET.description);
|
|
26
|
+
* console.log(envSchema.SPFN_AUTH_JWT_EXPIRES_IN.default);
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
declare const authEnvSchema: {
|
|
@@ -100,6 +100,16 @@ declare const authEnvSchema: {
|
|
|
100
100
|
} & {
|
|
101
101
|
key: "SPFN_AUTH_VERIFICATION_TOKEN_SECRET";
|
|
102
102
|
};
|
|
103
|
+
SPFN_AUTH_TOKEN_ENCRYPTION_KEYS: {
|
|
104
|
+
description: string;
|
|
105
|
+
required: boolean;
|
|
106
|
+
sensitive: boolean;
|
|
107
|
+
examples: string[];
|
|
108
|
+
type: "string";
|
|
109
|
+
validator: (value: string) => string;
|
|
110
|
+
} & {
|
|
111
|
+
key: "SPFN_AUTH_TOKEN_ENCRYPTION_KEYS";
|
|
112
|
+
};
|
|
103
113
|
SPFN_AUTH_ADMIN_ACCOUNTS: {
|
|
104
114
|
description: string;
|
|
105
115
|
required: boolean;
|
|
@@ -260,6 +270,154 @@ declare const authEnvSchema: {
|
|
|
260
270
|
} & {
|
|
261
271
|
key: "SPFN_AUTH_GOOGLE_REDIRECT_URI";
|
|
262
272
|
};
|
|
273
|
+
SPFN_AUTH_KAKAO_CLIENT_ID: {
|
|
274
|
+
description: string;
|
|
275
|
+
required: boolean;
|
|
276
|
+
examples: string[];
|
|
277
|
+
type: "string";
|
|
278
|
+
validator: (value: string) => string;
|
|
279
|
+
} & {
|
|
280
|
+
key: "SPFN_AUTH_KAKAO_CLIENT_ID";
|
|
281
|
+
};
|
|
282
|
+
SPFN_AUTH_KAKAO_CLIENT_SECRET: {
|
|
283
|
+
description: string;
|
|
284
|
+
required: boolean;
|
|
285
|
+
sensitive: boolean;
|
|
286
|
+
examples: string[];
|
|
287
|
+
type: "string";
|
|
288
|
+
validator: (value: string) => string;
|
|
289
|
+
} & {
|
|
290
|
+
key: "SPFN_AUTH_KAKAO_CLIENT_SECRET";
|
|
291
|
+
};
|
|
292
|
+
SPFN_AUTH_KAKAO_ADMIN_KEY: {
|
|
293
|
+
description: string;
|
|
294
|
+
required: boolean;
|
|
295
|
+
sensitive: boolean;
|
|
296
|
+
examples: string[];
|
|
297
|
+
type: "string";
|
|
298
|
+
validator: (value: string) => string;
|
|
299
|
+
} & {
|
|
300
|
+
key: "SPFN_AUTH_KAKAO_ADMIN_KEY";
|
|
301
|
+
};
|
|
302
|
+
SPFN_AUTH_KAKAO_SCOPES: {
|
|
303
|
+
description: string;
|
|
304
|
+
required: boolean;
|
|
305
|
+
examples: string[];
|
|
306
|
+
type: "string";
|
|
307
|
+
validator: (value: string) => string;
|
|
308
|
+
} & {
|
|
309
|
+
key: "SPFN_AUTH_KAKAO_SCOPES";
|
|
310
|
+
};
|
|
311
|
+
SPFN_AUTH_KAKAO_REDIRECT_URI: {
|
|
312
|
+
description: string;
|
|
313
|
+
required: boolean;
|
|
314
|
+
examples: string[];
|
|
315
|
+
type: "string";
|
|
316
|
+
validator: (value: string) => string;
|
|
317
|
+
} & {
|
|
318
|
+
key: "SPFN_AUTH_KAKAO_REDIRECT_URI";
|
|
319
|
+
};
|
|
320
|
+
SPFN_AUTH_NAVER_CLIENT_ID: {
|
|
321
|
+
description: string;
|
|
322
|
+
required: boolean;
|
|
323
|
+
examples: string[];
|
|
324
|
+
type: "string";
|
|
325
|
+
validator: (value: string) => string;
|
|
326
|
+
} & {
|
|
327
|
+
key: "SPFN_AUTH_NAVER_CLIENT_ID";
|
|
328
|
+
};
|
|
329
|
+
SPFN_AUTH_NAVER_CLIENT_SECRET: {
|
|
330
|
+
description: string;
|
|
331
|
+
required: boolean;
|
|
332
|
+
sensitive: boolean;
|
|
333
|
+
examples: string[];
|
|
334
|
+
type: "string";
|
|
335
|
+
validator: (value: string) => string;
|
|
336
|
+
} & {
|
|
337
|
+
key: "SPFN_AUTH_NAVER_CLIENT_SECRET";
|
|
338
|
+
};
|
|
339
|
+
SPFN_AUTH_NAVER_REDIRECT_URI: {
|
|
340
|
+
description: string;
|
|
341
|
+
required: boolean;
|
|
342
|
+
examples: string[];
|
|
343
|
+
type: "string";
|
|
344
|
+
validator: (value: string) => string;
|
|
345
|
+
} & {
|
|
346
|
+
key: "SPFN_AUTH_NAVER_REDIRECT_URI";
|
|
347
|
+
};
|
|
348
|
+
SPFN_AUTH_GITHUB_CLIENT_ID: {
|
|
349
|
+
description: string;
|
|
350
|
+
required: boolean;
|
|
351
|
+
examples: string[];
|
|
352
|
+
type: "string";
|
|
353
|
+
validator: (value: string) => string;
|
|
354
|
+
} & {
|
|
355
|
+
key: "SPFN_AUTH_GITHUB_CLIENT_ID";
|
|
356
|
+
};
|
|
357
|
+
SPFN_AUTH_GITHUB_CLIENT_SECRET: {
|
|
358
|
+
description: string;
|
|
359
|
+
required: boolean;
|
|
360
|
+
sensitive: boolean;
|
|
361
|
+
examples: string[];
|
|
362
|
+
type: "string";
|
|
363
|
+
validator: (value: string) => string;
|
|
364
|
+
} & {
|
|
365
|
+
key: "SPFN_AUTH_GITHUB_CLIENT_SECRET";
|
|
366
|
+
};
|
|
367
|
+
SPFN_AUTH_GITHUB_SCOPES: {
|
|
368
|
+
description: string;
|
|
369
|
+
required: boolean;
|
|
370
|
+
examples: string[];
|
|
371
|
+
type: "string";
|
|
372
|
+
validator: (value: string) => string;
|
|
373
|
+
} & {
|
|
374
|
+
key: "SPFN_AUTH_GITHUB_SCOPES";
|
|
375
|
+
};
|
|
376
|
+
SPFN_AUTH_GITHUB_REDIRECT_URI: {
|
|
377
|
+
description: string;
|
|
378
|
+
required: boolean;
|
|
379
|
+
examples: string[];
|
|
380
|
+
type: "string";
|
|
381
|
+
validator: (value: string) => string;
|
|
382
|
+
} & {
|
|
383
|
+
key: "SPFN_AUTH_GITHUB_REDIRECT_URI";
|
|
384
|
+
};
|
|
385
|
+
SPFN_AUTH_GOOGLE_NATIVE_CLIENT_IDS: {
|
|
386
|
+
description: string;
|
|
387
|
+
required: boolean;
|
|
388
|
+
examples: string[];
|
|
389
|
+
type: "string";
|
|
390
|
+
validator: (value: string) => string;
|
|
391
|
+
} & {
|
|
392
|
+
key: "SPFN_AUTH_GOOGLE_NATIVE_CLIENT_IDS";
|
|
393
|
+
};
|
|
394
|
+
SPFN_AUTH_APPLE_CLIENT_IDS: {
|
|
395
|
+
description: string;
|
|
396
|
+
required: boolean;
|
|
397
|
+
examples: string[];
|
|
398
|
+
type: "string";
|
|
399
|
+
validator: (value: string) => string;
|
|
400
|
+
} & {
|
|
401
|
+
key: "SPFN_AUTH_APPLE_CLIENT_IDS";
|
|
402
|
+
};
|
|
403
|
+
SPFN_AUTH_KAKAO_NATIVE_CLIENT_IDS: {
|
|
404
|
+
description: string;
|
|
405
|
+
required: boolean;
|
|
406
|
+
examples: string[];
|
|
407
|
+
type: "string";
|
|
408
|
+
validator: (value: string) => string;
|
|
409
|
+
} & {
|
|
410
|
+
key: "SPFN_AUTH_KAKAO_NATIVE_CLIENT_IDS";
|
|
411
|
+
};
|
|
412
|
+
SPFN_AUTH_NAVER_NATIVE_CLIENT_IDS: {
|
|
413
|
+
description: string;
|
|
414
|
+
required: boolean;
|
|
415
|
+
examples: string[];
|
|
416
|
+
type: "string";
|
|
417
|
+
validator: (value: string) => string;
|
|
418
|
+
} & {
|
|
419
|
+
key: "SPFN_AUTH_NAVER_NATIVE_CLIENT_IDS";
|
|
420
|
+
};
|
|
263
421
|
SPFN_AUTH_OAUTH_SUCCESS_URL: {
|
|
264
422
|
description: string;
|
|
265
423
|
required: boolean;
|
|
@@ -356,6 +514,16 @@ declare const env: _spfn_core_env.InferEnvType<{
|
|
|
356
514
|
} & {
|
|
357
515
|
key: "SPFN_AUTH_VERIFICATION_TOKEN_SECRET";
|
|
358
516
|
};
|
|
517
|
+
SPFN_AUTH_TOKEN_ENCRYPTION_KEYS: {
|
|
518
|
+
description: string;
|
|
519
|
+
required: boolean;
|
|
520
|
+
sensitive: boolean;
|
|
521
|
+
examples: string[];
|
|
522
|
+
type: "string";
|
|
523
|
+
validator: (value: string) => string;
|
|
524
|
+
} & {
|
|
525
|
+
key: "SPFN_AUTH_TOKEN_ENCRYPTION_KEYS";
|
|
526
|
+
};
|
|
359
527
|
SPFN_AUTH_ADMIN_ACCOUNTS: {
|
|
360
528
|
description: string;
|
|
361
529
|
required: boolean;
|
|
@@ -516,6 +684,154 @@ declare const env: _spfn_core_env.InferEnvType<{
|
|
|
516
684
|
} & {
|
|
517
685
|
key: "SPFN_AUTH_GOOGLE_REDIRECT_URI";
|
|
518
686
|
};
|
|
687
|
+
SPFN_AUTH_KAKAO_CLIENT_ID: {
|
|
688
|
+
description: string;
|
|
689
|
+
required: boolean;
|
|
690
|
+
examples: string[];
|
|
691
|
+
type: "string";
|
|
692
|
+
validator: (value: string) => string;
|
|
693
|
+
} & {
|
|
694
|
+
key: "SPFN_AUTH_KAKAO_CLIENT_ID";
|
|
695
|
+
};
|
|
696
|
+
SPFN_AUTH_KAKAO_CLIENT_SECRET: {
|
|
697
|
+
description: string;
|
|
698
|
+
required: boolean;
|
|
699
|
+
sensitive: boolean;
|
|
700
|
+
examples: string[];
|
|
701
|
+
type: "string";
|
|
702
|
+
validator: (value: string) => string;
|
|
703
|
+
} & {
|
|
704
|
+
key: "SPFN_AUTH_KAKAO_CLIENT_SECRET";
|
|
705
|
+
};
|
|
706
|
+
SPFN_AUTH_KAKAO_ADMIN_KEY: {
|
|
707
|
+
description: string;
|
|
708
|
+
required: boolean;
|
|
709
|
+
sensitive: boolean;
|
|
710
|
+
examples: string[];
|
|
711
|
+
type: "string";
|
|
712
|
+
validator: (value: string) => string;
|
|
713
|
+
} & {
|
|
714
|
+
key: "SPFN_AUTH_KAKAO_ADMIN_KEY";
|
|
715
|
+
};
|
|
716
|
+
SPFN_AUTH_KAKAO_SCOPES: {
|
|
717
|
+
description: string;
|
|
718
|
+
required: boolean;
|
|
719
|
+
examples: string[];
|
|
720
|
+
type: "string";
|
|
721
|
+
validator: (value: string) => string;
|
|
722
|
+
} & {
|
|
723
|
+
key: "SPFN_AUTH_KAKAO_SCOPES";
|
|
724
|
+
};
|
|
725
|
+
SPFN_AUTH_KAKAO_REDIRECT_URI: {
|
|
726
|
+
description: string;
|
|
727
|
+
required: boolean;
|
|
728
|
+
examples: string[];
|
|
729
|
+
type: "string";
|
|
730
|
+
validator: (value: string) => string;
|
|
731
|
+
} & {
|
|
732
|
+
key: "SPFN_AUTH_KAKAO_REDIRECT_URI";
|
|
733
|
+
};
|
|
734
|
+
SPFN_AUTH_NAVER_CLIENT_ID: {
|
|
735
|
+
description: string;
|
|
736
|
+
required: boolean;
|
|
737
|
+
examples: string[];
|
|
738
|
+
type: "string";
|
|
739
|
+
validator: (value: string) => string;
|
|
740
|
+
} & {
|
|
741
|
+
key: "SPFN_AUTH_NAVER_CLIENT_ID";
|
|
742
|
+
};
|
|
743
|
+
SPFN_AUTH_NAVER_CLIENT_SECRET: {
|
|
744
|
+
description: string;
|
|
745
|
+
required: boolean;
|
|
746
|
+
sensitive: boolean;
|
|
747
|
+
examples: string[];
|
|
748
|
+
type: "string";
|
|
749
|
+
validator: (value: string) => string;
|
|
750
|
+
} & {
|
|
751
|
+
key: "SPFN_AUTH_NAVER_CLIENT_SECRET";
|
|
752
|
+
};
|
|
753
|
+
SPFN_AUTH_NAVER_REDIRECT_URI: {
|
|
754
|
+
description: string;
|
|
755
|
+
required: boolean;
|
|
756
|
+
examples: string[];
|
|
757
|
+
type: "string";
|
|
758
|
+
validator: (value: string) => string;
|
|
759
|
+
} & {
|
|
760
|
+
key: "SPFN_AUTH_NAVER_REDIRECT_URI";
|
|
761
|
+
};
|
|
762
|
+
SPFN_AUTH_GITHUB_CLIENT_ID: {
|
|
763
|
+
description: string;
|
|
764
|
+
required: boolean;
|
|
765
|
+
examples: string[];
|
|
766
|
+
type: "string";
|
|
767
|
+
validator: (value: string) => string;
|
|
768
|
+
} & {
|
|
769
|
+
key: "SPFN_AUTH_GITHUB_CLIENT_ID";
|
|
770
|
+
};
|
|
771
|
+
SPFN_AUTH_GITHUB_CLIENT_SECRET: {
|
|
772
|
+
description: string;
|
|
773
|
+
required: boolean;
|
|
774
|
+
sensitive: boolean;
|
|
775
|
+
examples: string[];
|
|
776
|
+
type: "string";
|
|
777
|
+
validator: (value: string) => string;
|
|
778
|
+
} & {
|
|
779
|
+
key: "SPFN_AUTH_GITHUB_CLIENT_SECRET";
|
|
780
|
+
};
|
|
781
|
+
SPFN_AUTH_GITHUB_SCOPES: {
|
|
782
|
+
description: string;
|
|
783
|
+
required: boolean;
|
|
784
|
+
examples: string[];
|
|
785
|
+
type: "string";
|
|
786
|
+
validator: (value: string) => string;
|
|
787
|
+
} & {
|
|
788
|
+
key: "SPFN_AUTH_GITHUB_SCOPES";
|
|
789
|
+
};
|
|
790
|
+
SPFN_AUTH_GITHUB_REDIRECT_URI: {
|
|
791
|
+
description: string;
|
|
792
|
+
required: boolean;
|
|
793
|
+
examples: string[];
|
|
794
|
+
type: "string";
|
|
795
|
+
validator: (value: string) => string;
|
|
796
|
+
} & {
|
|
797
|
+
key: "SPFN_AUTH_GITHUB_REDIRECT_URI";
|
|
798
|
+
};
|
|
799
|
+
SPFN_AUTH_GOOGLE_NATIVE_CLIENT_IDS: {
|
|
800
|
+
description: string;
|
|
801
|
+
required: boolean;
|
|
802
|
+
examples: string[];
|
|
803
|
+
type: "string";
|
|
804
|
+
validator: (value: string) => string;
|
|
805
|
+
} & {
|
|
806
|
+
key: "SPFN_AUTH_GOOGLE_NATIVE_CLIENT_IDS";
|
|
807
|
+
};
|
|
808
|
+
SPFN_AUTH_APPLE_CLIENT_IDS: {
|
|
809
|
+
description: string;
|
|
810
|
+
required: boolean;
|
|
811
|
+
examples: string[];
|
|
812
|
+
type: "string";
|
|
813
|
+
validator: (value: string) => string;
|
|
814
|
+
} & {
|
|
815
|
+
key: "SPFN_AUTH_APPLE_CLIENT_IDS";
|
|
816
|
+
};
|
|
817
|
+
SPFN_AUTH_KAKAO_NATIVE_CLIENT_IDS: {
|
|
818
|
+
description: string;
|
|
819
|
+
required: boolean;
|
|
820
|
+
examples: string[];
|
|
821
|
+
type: "string";
|
|
822
|
+
validator: (value: string) => string;
|
|
823
|
+
} & {
|
|
824
|
+
key: "SPFN_AUTH_KAKAO_NATIVE_CLIENT_IDS";
|
|
825
|
+
};
|
|
826
|
+
SPFN_AUTH_NAVER_NATIVE_CLIENT_IDS: {
|
|
827
|
+
description: string;
|
|
828
|
+
required: boolean;
|
|
829
|
+
examples: string[];
|
|
830
|
+
type: "string";
|
|
831
|
+
validator: (value: string) => string;
|
|
832
|
+
} & {
|
|
833
|
+
key: "SPFN_AUTH_NAVER_NATIVE_CLIENT_IDS";
|
|
834
|
+
};
|
|
519
835
|
SPFN_AUTH_OAUTH_SUCCESS_URL: {
|
|
520
836
|
description: string;
|
|
521
837
|
required: boolean;
|
package/dist/config.js
CHANGED
|
@@ -79,7 +79,7 @@ var authEnvSchema = defineEnvSchema({
|
|
|
79
79
|
SPFN_AUTH_BCRYPT_SALT_ROUNDS: {
|
|
80
80
|
...envNumber({
|
|
81
81
|
description: "Bcrypt salt rounds (cost factor, higher = more secure but slower)",
|
|
82
|
-
default:
|
|
82
|
+
default: 12,
|
|
83
83
|
required: false,
|
|
84
84
|
examples: [10, 12, 14]
|
|
85
85
|
}),
|
|
@@ -95,6 +95,16 @@ var authEnvSchema = defineEnvSchema({
|
|
|
95
95
|
]
|
|
96
96
|
})
|
|
97
97
|
},
|
|
98
|
+
SPFN_AUTH_TOKEN_ENCRYPTION_KEYS: {
|
|
99
|
+
...envString({
|
|
100
|
+
description: "Backend-only OAuth token encryption keyring. Comma-separated <keyId>:<base64-encoded 32-byte key> entries; the first key encrypts new values and remaining keys decrypt during rotation.",
|
|
101
|
+
required: false,
|
|
102
|
+
sensitive: true,
|
|
103
|
+
examples: [
|
|
104
|
+
"v2:<base64-encoded-32-byte-key>,v1:<previous-base64-encoded-32-byte-key>"
|
|
105
|
+
]
|
|
106
|
+
})
|
|
107
|
+
},
|
|
98
108
|
// ============================================================================
|
|
99
109
|
// Admin Account Configuration
|
|
100
110
|
// ============================================================================
|
|
@@ -206,7 +216,7 @@ var authEnvSchema = defineEnvSchema({
|
|
|
206
216
|
},
|
|
207
217
|
NEXT_PUBLIC_SPFN_API_URL: {
|
|
208
218
|
...envString({
|
|
209
|
-
description: "Public-facing API URL used for browser-facing redirects
|
|
219
|
+
description: "Public-facing API URL used for browser-facing redirects. Falls back to SPFN_API_URL if not set.",
|
|
210
220
|
required: false,
|
|
211
221
|
examples: [
|
|
212
222
|
"https://api.example.com",
|
|
@@ -266,11 +276,151 @@ var authEnvSchema = defineEnvSchema({
|
|
|
266
276
|
},
|
|
267
277
|
SPFN_AUTH_GOOGLE_REDIRECT_URI: {
|
|
268
278
|
...envString({
|
|
269
|
-
description: "Google OAuth callback URL. Defaults to {
|
|
279
|
+
description: "Google OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/google/callback \u2014 the callback must return to the web app origin that set the oauth_csrf cookie (the app rewrites /_auth/:path* to the API). Set this explicitly only when the callback should hit a different host (e.g. the API host for the direct oauthStart flow).",
|
|
280
|
+
required: false,
|
|
281
|
+
examples: [
|
|
282
|
+
"https://app.example.com/_auth/oauth/google/callback",
|
|
283
|
+
"http://localhost:3000/_auth/oauth/google/callback"
|
|
284
|
+
]
|
|
285
|
+
})
|
|
286
|
+
},
|
|
287
|
+
// ============================================================================
|
|
288
|
+
// OAuth Configuration - Kakao
|
|
289
|
+
// ============================================================================
|
|
290
|
+
SPFN_AUTH_KAKAO_CLIENT_ID: {
|
|
291
|
+
...envString({
|
|
292
|
+
description: "Kakao Login REST API key. Used as the OAuth client_id.",
|
|
293
|
+
required: false,
|
|
294
|
+
examples: ["your-kakao-rest-api-key"]
|
|
295
|
+
})
|
|
296
|
+
},
|
|
297
|
+
SPFN_AUTH_KAKAO_CLIENT_SECRET: {
|
|
298
|
+
...envString({
|
|
299
|
+
description: "Kakao Login client secret. Required when the Kakao client-secret feature is enabled.",
|
|
300
|
+
required: false,
|
|
301
|
+
sensitive: true,
|
|
302
|
+
examples: ["your-kakao-client-secret"]
|
|
303
|
+
})
|
|
304
|
+
},
|
|
305
|
+
SPFN_AUTH_KAKAO_ADMIN_KEY: {
|
|
306
|
+
...envString({
|
|
307
|
+
description: "Kakao app admin key. Required to verify the User Unlinked webhook (Authorization: KakaoAK header).",
|
|
308
|
+
required: false,
|
|
309
|
+
sensitive: true,
|
|
310
|
+
examples: ["your-kakao-admin-key"]
|
|
311
|
+
})
|
|
312
|
+
},
|
|
313
|
+
SPFN_AUTH_KAKAO_SCOPES: {
|
|
314
|
+
...envString({
|
|
315
|
+
description: "Comma-separated Kakao consent scopes. Defaults to account_email.",
|
|
316
|
+
required: false,
|
|
317
|
+
examples: ["account_email"]
|
|
318
|
+
})
|
|
319
|
+
},
|
|
320
|
+
SPFN_AUTH_KAKAO_REDIRECT_URI: {
|
|
321
|
+
...envString({
|
|
322
|
+
description: "Kakao OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/kakao/callback.",
|
|
323
|
+
required: false,
|
|
324
|
+
examples: ["https://app.example.com/_auth/oauth/kakao/callback"]
|
|
325
|
+
})
|
|
326
|
+
},
|
|
327
|
+
// ============================================================================
|
|
328
|
+
// OAuth Configuration - Naver
|
|
329
|
+
// ============================================================================
|
|
330
|
+
SPFN_AUTH_NAVER_CLIENT_ID: {
|
|
331
|
+
...envString({
|
|
332
|
+
description: "Naver Login OAuth client ID.",
|
|
333
|
+
required: false,
|
|
334
|
+
examples: ["your-naver-client-id"]
|
|
335
|
+
})
|
|
336
|
+
},
|
|
337
|
+
SPFN_AUTH_NAVER_CLIENT_SECRET: {
|
|
338
|
+
...envString({
|
|
339
|
+
description: "Naver Login OAuth client secret.",
|
|
340
|
+
required: false,
|
|
341
|
+
sensitive: true,
|
|
342
|
+
examples: ["your-naver-client-secret"]
|
|
343
|
+
})
|
|
344
|
+
},
|
|
345
|
+
SPFN_AUTH_NAVER_REDIRECT_URI: {
|
|
346
|
+
...envString({
|
|
347
|
+
description: "Naver OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/naver/callback.",
|
|
348
|
+
required: false,
|
|
349
|
+
examples: ["https://app.example.com/_auth/oauth/naver/callback"]
|
|
350
|
+
})
|
|
351
|
+
},
|
|
352
|
+
// ============================================================================
|
|
353
|
+
// OAuth Configuration - GitHub
|
|
354
|
+
// ============================================================================
|
|
355
|
+
SPFN_AUTH_GITHUB_CLIENT_ID: {
|
|
356
|
+
...envString({
|
|
357
|
+
description: "GitHub OAuth app client ID. When set, GitHub OAuth routes are automatically enabled.",
|
|
358
|
+
required: false,
|
|
359
|
+
examples: ["Iv1.abc123def456"]
|
|
360
|
+
})
|
|
361
|
+
},
|
|
362
|
+
SPFN_AUTH_GITHUB_CLIENT_SECRET: {
|
|
363
|
+
...envString({
|
|
364
|
+
description: "GitHub OAuth app client secret.",
|
|
365
|
+
required: false,
|
|
366
|
+
sensitive: true,
|
|
367
|
+
examples: ["your-github-client-secret"]
|
|
368
|
+
})
|
|
369
|
+
},
|
|
370
|
+
SPFN_AUTH_GITHUB_SCOPES: {
|
|
371
|
+
...envString({
|
|
372
|
+
description: 'Comma-separated GitHub OAuth scopes. Defaults to "read:user,user:email".',
|
|
373
|
+
required: false,
|
|
374
|
+
examples: ["read:user,user:email"]
|
|
375
|
+
})
|
|
376
|
+
},
|
|
377
|
+
SPFN_AUTH_GITHUB_REDIRECT_URI: {
|
|
378
|
+
...envString({
|
|
379
|
+
description: "GitHub OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/github/callback.",
|
|
380
|
+
required: false,
|
|
381
|
+
examples: ["https://app.example.com/_auth/oauth/github/callback"]
|
|
382
|
+
})
|
|
383
|
+
},
|
|
384
|
+
// ============================================================================
|
|
385
|
+
// Native Social Login (mobile/web id_token verification)
|
|
386
|
+
//
|
|
387
|
+
// 네이티브 SDK가 받은 id_token을 서버가 JWKS로 검증하는 경로 전용 설정.
|
|
388
|
+
// authorization code 교환을 하지 않으므로 client secret이 필요 없다.
|
|
389
|
+
// audience(aud)로 허용할 client id 목록만 지정한다.
|
|
390
|
+
// ============================================================================
|
|
391
|
+
SPFN_AUTH_GOOGLE_NATIVE_CLIENT_IDS: {
|
|
392
|
+
...envString({
|
|
393
|
+
description: "Comma-separated Google client IDs accepted as id_token audience for native sign-in (iOS, Android, web). When set, Google native sign-in is enabled. SPFN_AUTH_GOOGLE_CLIENT_ID is also accepted automatically.",
|
|
394
|
+
required: false,
|
|
395
|
+
examples: [
|
|
396
|
+
"123-ios.apps.googleusercontent.com,123-android.apps.googleusercontent.com"
|
|
397
|
+
]
|
|
398
|
+
})
|
|
399
|
+
},
|
|
400
|
+
SPFN_AUTH_APPLE_CLIENT_IDS: {
|
|
401
|
+
...envString({
|
|
402
|
+
description: "Comma-separated Apple client IDs accepted as id_token audience for native sign-in (iOS bundle ID, web/Android Services ID). When set, Apple native sign-in is enabled.",
|
|
403
|
+
required: false,
|
|
404
|
+
examples: [
|
|
405
|
+
"com.example.app,com.example.app.service"
|
|
406
|
+
]
|
|
407
|
+
})
|
|
408
|
+
},
|
|
409
|
+
SPFN_AUTH_KAKAO_NATIVE_CLIENT_IDS: {
|
|
410
|
+
...envString({
|
|
411
|
+
description: "Comma-separated Kakao app keys accepted as id_token audience for native sign-in (native app key). SPFN_AUTH_KAKAO_CLIENT_ID (REST API key) is also accepted automatically, so native sign-in is available when either variable is set. Requires OpenID Connect to be enabled in the Kakao developer console.",
|
|
412
|
+
required: false,
|
|
413
|
+
examples: [
|
|
414
|
+
"your-kakao-native-app-key"
|
|
415
|
+
]
|
|
416
|
+
})
|
|
417
|
+
},
|
|
418
|
+
SPFN_AUTH_NAVER_NATIVE_CLIENT_IDS: {
|
|
419
|
+
...envString({
|
|
420
|
+
description: "Comma-separated Naver client IDs accepted as id_token audience for native sign-in. SPFN_AUTH_NAVER_CLIENT_ID is also accepted automatically, and one Naver application has a single client ID covering web and app environments \u2014 set this only when the app uses a separate application.",
|
|
270
421
|
required: false,
|
|
271
422
|
examples: [
|
|
272
|
-
"
|
|
273
|
-
"http://localhost:8790/_auth/oauth/google/callback"
|
|
423
|
+
"your-naver-app-client-id"
|
|
274
424
|
]
|
|
275
425
|
})
|
|
276
426
|
},
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/index.ts","../src/config/schema.ts"],"sourcesContent":["/**\n * Core Package Configuration\n *\n * @example\n * ```typescript\n * import { registry } from '@spfn/core/config';\n *\n * const env = registry.validate();\n * console.log(env.DB_POOL_MAX);\n * ```\n *\n * @module config\n */\n\nimport { createEnvRegistry } from '@spfn/core/env';\nimport { authEnvSchema } from './schema';\n\nexport { authEnvSchema as envSchema } from './schema';\n\n/**\n * Environment registry\n */\nconst registry = createEnvRegistry(authEnvSchema);\nexport const env = registry.validate();","/**\n * Auth Environment Variable Schema\n *\n * Centralized schema definition for all environment variables used in @spfn/auth.\n * This provides type safety, validation, and documentation for Auth configuration.\n *\n * @module config/schema\n */\n\nimport {\n defineEnvSchema,\n envString,\n envNumber,\n envBoolean,\n createSecureSecretParser,\n createPasswordParser,\n} from '@spfn/core/env';\n\n/**\n * Auth environment variable schema\n *\n * Defines all Auth environment variables with:\n * - Type information\n * - Default values\n * - Validation rules\n * - Documentation\n *\n * @example\n * ```typescript\n * import { authEnvSchema } from '@spfn/auth/config';\n *\n * // Access schema information\n * console.log(authEnvSchema.SPFN_AUTH_SESSION_SECRET.description);\n * console.log(authEnvSchema.SPFN_AUTH_JWT_EXPIRES_IN.default);\n * ```\n */\nexport const authEnvSchema = defineEnvSchema({\n // ============================================================================\n // Session Configuration\n // ============================================================================\n SPFN_AUTH_SESSION_SECRET: {\n ...envString({\n description: 'Session encryption secret (minimum 32 characters for AES-256)',\n required: true,\n fallbackKeys: ['SESSION_SECRET'],\n validator: createSecureSecretParser({\n minLength: 32,\n minUniqueChars: 16,\n minEntropy: 3.5,\n }),\n sensitive: true,\n nextjs: true, // Required for Next.js RSC session validation\n examples: [\n 'my-super-secret-session-key-at-least-32-chars-long',\n 'use-a-cryptographically-secure-random-string-here',\n ],\n }),\n },\n\n SPFN_AUTH_SESSION_TTL: {\n ...envString({\n description: 'Session TTL (time to live) - supports duration strings like \\'7d\\', \\'12h\\', \\'45m\\'',\n default: '7d',\n required: false,\n nextjs: true, // May be needed for session validation in Next.js RSC\n examples: ['7d', '30d', '12h', '45m', '3600'],\n }),\n },\n\n // ============================================================================\n // JWT Configuration\n // ============================================================================\n SPFN_AUTH_JWT_SECRET: {\n ...envString({\n description: 'JWT signing secret for server-signed tokens (legacy mode)',\n default: 'dev-secret-key-change-in-production',\n required: false,\n examples: [\n 'your-jwt-secret-key-here',\n 'use-different-from-session-secret',\n ],\n }),\n },\n\n SPFN_AUTH_JWT_EXPIRES_IN: {\n ...envString({\n description: 'JWT token expiration time (e.g., \\'7d\\', \\'24h\\', \\'1h\\')',\n default: '7d',\n required: false,\n examples: ['7d', '24h', '1h', '30m'],\n }),\n },\n\n // ============================================================================\n // Security Configuration\n // ============================================================================\n SPFN_AUTH_COOKIE_SECURE: {\n ...envBoolean({\n description: 'Override cookie Secure flag. Defaults to NODE_ENV === \"production\". Set to false for HTTP-only environments (e.g. bastion over plain HTTP).',\n required: false,\n nextjs: true,\n examples: [true, false],\n }),\n },\n\n SPFN_AUTH_BCRYPT_SALT_ROUNDS: {\n ...envNumber({\n description: 'Bcrypt salt rounds (cost factor, higher = more secure but slower)',\n default: 10,\n required: false,\n examples: [10, 12, 14],\n }),\n key: 'SPFN_AUTH_BCRYPT_SALT_ROUNDS',\n },\n\n SPFN_AUTH_VERIFICATION_TOKEN_SECRET: {\n ...envString({\n description: 'Verification token secret for email verification, password reset, etc.',\n required: true,\n examples: [\n 'your-verification-token-secret',\n 'can-be-different-from-jwt-secret',\n ],\n }),\n },\n\n // ============================================================================\n // Admin Account Configuration\n // ============================================================================\n SPFN_AUTH_ADMIN_ACCOUNTS: {\n ...envString({\n description: 'JSON array of admin accounts (recommended for multiple admins)',\n required: false,\n examples: [\n '[{\"email\":\"admin@example.com\",\"password\":\"secure-pass\",\"role\":\"admin\"}]',\n '[{\"email\":\"super@example.com\",\"password\":\"pass1\",\"role\":\"superadmin\"},{\"email\":\"admin@example.com\",\"password\":\"pass2\",\"role\":\"admin\"}]',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_EMAILS: {\n ...envString({\n description: 'Comma-separated list of admin emails (legacy CSV format)',\n required: false,\n examples: [\n 'admin@example.com,user@example.com',\n 'super@example.com,admin@example.com,user@example.com',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_PASSWORDS: {\n ...envString({\n description: 'Comma-separated list of admin passwords (legacy CSV format)',\n required: false,\n examples: [\n 'admin-pass,user-pass',\n 'super-pass,admin-pass,user-pass',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_ROLES: {\n ...envString({\n description: 'Comma-separated list of admin roles (legacy CSV format)',\n required: false,\n examples: [\n 'admin,user',\n 'superadmin,admin,user',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_EMAIL: {\n ...envString({\n description: 'Single admin email (simplest format)',\n required: false,\n examples: ['admin@example.com'],\n }),\n },\n\n SPFN_AUTH_ADMIN_PASSWORD: {\n ...envString({\n description: 'Single admin password (simplest format)',\n required: false,\n validator: createPasswordParser({\n minLength: 8,\n requireUppercase: true,\n requireLowercase: true,\n requireNumber: true,\n requireSpecial: true,\n }),\n sensitive: true,\n examples: ['SecureAdmin123!'],\n }),\n },\n\n // ============================================================================\n // Username Configuration\n // ============================================================================\n SPFN_AUTH_RESERVED_USERNAMES: {\n ...envString({\n description: 'Comma-separated list of reserved usernames that cannot be registered',\n required: false,\n default: 'admin,root,system,support,help,moderator,superadmin',\n examples: [\n 'admin,root,system,support,help',\n 'admin,root,system,support,help,moderator,superadmin,operator',\n ],\n }),\n },\n\n SPFN_AUTH_USERNAME_MIN_LENGTH: {\n ...envNumber({\n description: 'Minimum username length',\n default: 3,\n required: false,\n examples: [2, 3, 4],\n }),\n },\n\n SPFN_AUTH_USERNAME_MAX_LENGTH: {\n ...envNumber({\n description: 'Maximum username length',\n default: 30,\n required: false,\n examples: [20, 30, 50],\n }),\n },\n\n // ============================================================================\n // API Configuration\n // ============================================================================\n SPFN_API_URL: {\n ...envString({\n description: 'Internal API URL for server-to-server communication',\n default: 'http://localhost:8790',\n required: false,\n examples: [\n 'https://api.example.com',\n 'http://localhost:8790',\n ],\n }),\n },\n\n NEXT_PUBLIC_SPFN_API_URL: {\n ...envString({\n description: 'Public-facing API URL used for browser-facing redirects (e.g. OAuth callback). Falls back to SPFN_API_URL if not set.',\n required: false,\n examples: [\n 'https://api.example.com',\n 'http://localhost:8790',\n ],\n }),\n },\n\n SPFN_APP_URL: {\n ...envString({\n description: 'Next.js application URL (internal). Used for server-to-server communication.',\n default: 'http://localhost:3000',\n required: false,\n examples: [\n 'https://app.example.com',\n 'http://localhost:3000',\n ],\n }),\n },\n\n NEXT_PUBLIC_SPFN_APP_URL: {\n ...envString({\n description: 'Public-facing Next.js app URL for browser redirects (e.g. OAuth redirect). Falls back to SPFN_APP_URL if not set.',\n required: false,\n examples: [\n 'https://app.example.com',\n 'http://localhost:3000',\n ],\n }),\n },\n\n // ============================================================================\n // OAuth Configuration - Google\n // ============================================================================\n SPFN_AUTH_GOOGLE_CLIENT_ID: {\n ...envString({\n description: 'Google OAuth 2.0 Client ID. When set, Google OAuth routes are automatically enabled.',\n required: false,\n examples: ['123456789-abc123.apps.googleusercontent.com'],\n }),\n },\n\n SPFN_AUTH_GOOGLE_CLIENT_SECRET: {\n ...envString({\n description: 'Google OAuth 2.0 Client Secret',\n required: false,\n sensitive: true,\n examples: ['GOCSPX-abcdefghijklmnop'],\n }),\n },\n\n SPFN_AUTH_GOOGLE_SCOPES: {\n ...envString({\n description: 'Comma-separated Google OAuth scopes. Defaults to \"email,profile\" if not set.',\n required: false,\n examples: [\n 'email,profile',\n 'email,profile,https://www.googleapis.com/auth/gmail.readonly',\n 'email,profile,https://www.googleapis.com/auth/calendar.readonly',\n ],\n }),\n },\n\n SPFN_AUTH_GOOGLE_REDIRECT_URI: {\n ...envString({\n description: 'Google OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_API_URL || SPFN_API_URL}/_auth/oauth/google/callback',\n required: false,\n examples: [\n 'https://api.example.com/_auth/oauth/google/callback',\n 'http://localhost:8790/_auth/oauth/google/callback',\n ],\n }),\n },\n\n SPFN_AUTH_OAUTH_SUCCESS_URL: {\n ...envString({\n description: 'OAuth callback page URL. This page should use OAuthCallback component to finalize session.',\n required: false,\n default: '/auth/callback',\n examples: [\n '/auth/callback',\n 'https://app.example.com/auth/callback',\n ],\n }),\n },\n\n SPFN_AUTH_OAUTH_ERROR_URL: {\n ...envString({\n description: 'URL to redirect after OAuth error. Use {error} placeholder for error message.',\n required: false,\n default: '/auth/error?error={error}',\n examples: [\n 'https://app.example.com/auth/error?error={error}',\n 'http://localhost:3000/auth/error?error={error}',\n ],\n }),\n },\n});"],"mappings":";AAcA,SAAS,yBAAyB;;;ACLlC;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AAoBA,IAAM,gBAAgB,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAIzC,0BAA0B;AAAA,IACtB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,cAAc,CAAC,gBAAgB;AAAA,MAC/B,WAAW,yBAAyB;AAAA,QAChC,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,YAAY;AAAA,MAChB,CAAC;AAAA,MACD,WAAW;AAAA,MACX,QAAQ;AAAA;AAAA,MACR,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,uBAAuB;AAAA,IACnB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,QAAQ;AAAA;AAAA,MACR,UAAU,CAAC,MAAM,OAAO,OAAO,OAAO,MAAM;AAAA,IAChD,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB;AAAA,IAClB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,0BAA0B;AAAA,IACtB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU,CAAC,MAAM,OAAO,MAAM,KAAK;AAAA,IACvC,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAyB;AAAA,IACrB,GAAG,WAAW;AAAA,MACV,aAAa;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU,CAAC,MAAM,KAAK;AAAA,IAC1B,CAAC;AAAA,EACL;AAAA,EAEA,8BAA8B;AAAA,IAC1B,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU,CAAC,IAAI,IAAI,EAAE;AAAA,IACzB,CAAC;AAAA,IACD,KAAK;AAAA,EACT;AAAA,EAEA,qCAAqC;AAAA,IACjC,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,0BAA0B;AAAA,IACtB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,wBAAwB;AAAA,IACpB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,2BAA2B;AAAA,IACvB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,uBAAuB;AAAA,IACnB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,uBAAuB;AAAA,IACnB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU,CAAC,mBAAmB;AAAA,IAClC,CAAC;AAAA,EACL;AAAA,EAEA,0BAA0B;AAAA,IACtB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,WAAW,qBAAqB;AAAA,QAC5B,WAAW;AAAA,QACX,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,QAClB,eAAe;AAAA,QACf,gBAAgB;AAAA,MACpB,CAAC;AAAA,MACD,WAAW;AAAA,MACX,UAAU,CAAC,iBAAiB;AAAA,IAChC,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,8BAA8B;AAAA,IAC1B,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,+BAA+B;AAAA,IAC3B,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU,CAAC,GAAG,GAAG,CAAC;AAAA,IACtB,CAAC;AAAA,EACL;AAAA,EAEA,+BAA+B;AAAA,IAC3B,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU,CAAC,IAAI,IAAI,EAAE;AAAA,IACzB,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AAAA,IACV,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,0BAA0B;AAAA,IACtB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,cAAc;AAAA,IACV,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,0BAA0B;AAAA,IACtB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,4BAA4B;AAAA,IACxB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU,CAAC,6CAA6C;AAAA,IAC5D,CAAC;AAAA,EACL;AAAA,EAEA,gCAAgC;AAAA,IAC5B,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU,CAAC,yBAAyB;AAAA,IACxC,CAAC;AAAA,EACL;AAAA,EAEA,yBAAyB;AAAA,IACrB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,+BAA+B;AAAA,IAC3B,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,6BAA6B;AAAA,IACzB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,2BAA2B;AAAA,IACvB,GAAG,UAAU;AAAA,MACT,aAAa;AAAA,MACb,UAAU;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,QACN;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AACJ,CAAC;;;ADnUD,IAAM,WAAW,kBAAkB,aAAa;AACzC,IAAM,MAAM,SAAS,SAAS;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/config/index.ts","../src/config/schema.ts"],"sourcesContent":["/**\n * Core Package Configuration\n *\n * @example\n * ```typescript\n * import { registry } from '@spfn/core/config';\n *\n * const env = registry.validate();\n * console.log(env.DB_POOL_MAX);\n * ```\n *\n * @module config\n */\n\nimport { createEnvRegistry } from '@spfn/core/env';\nimport { authEnvSchema } from './schema';\n\nexport { authEnvSchema as envSchema } from './schema';\n\n/**\n * Environment registry\n */\nconst registry = createEnvRegistry(authEnvSchema);\nexport const env = registry.validate();\n","/**\n * Auth Environment Variable Schema\n *\n * Centralized schema definition for all environment variables used in @spfn/auth.\n * This provides type safety, validation, and documentation for Auth configuration.\n *\n * @module config/schema\n */\n\nimport {\n defineEnvSchema,\n envString,\n envNumber,\n envBoolean,\n createSecureSecretParser,\n createPasswordParser,\n} from '@spfn/core/env';\n\n/**\n * Auth environment variable schema\n *\n * Defines all Auth environment variables with:\n * - Type information\n * - Default values\n * - Validation rules\n * - Documentation\n *\n * @example\n * ```typescript\n * import { envSchema } from '@spfn/auth/config';\n *\n * // Access schema information\n * console.log(envSchema.SPFN_AUTH_SESSION_SECRET.description);\n * console.log(envSchema.SPFN_AUTH_JWT_EXPIRES_IN.default);\n * ```\n */\nexport const authEnvSchema = defineEnvSchema({\n // ============================================================================\n // Session Configuration\n // ============================================================================\n SPFN_AUTH_SESSION_SECRET: {\n ...envString({\n description: 'Session encryption secret (minimum 32 characters for AES-256)',\n required: true,\n fallbackKeys: ['SESSION_SECRET'],\n validator: createSecureSecretParser({\n minLength: 32,\n minUniqueChars: 16,\n minEntropy: 3.5,\n }),\n sensitive: true,\n nextjs: true, // Required for Next.js RSC session validation\n examples: [\n 'my-super-secret-session-key-at-least-32-chars-long',\n 'use-a-cryptographically-secure-random-string-here',\n ],\n }),\n },\n\n SPFN_AUTH_SESSION_TTL: {\n ...envString({\n description: 'Session TTL (time to live) - supports duration strings like \\'7d\\', \\'12h\\', \\'45m\\'',\n default: '7d',\n required: false,\n nextjs: true, // May be needed for session validation in Next.js RSC\n examples: ['7d', '30d', '12h', '45m', '3600'],\n }),\n },\n\n // ============================================================================\n // JWT Configuration\n // ============================================================================\n SPFN_AUTH_JWT_SECRET: {\n ...envString({\n description: 'JWT signing secret for server-signed tokens (legacy mode)',\n default: 'dev-secret-key-change-in-production',\n required: false,\n examples: [\n 'your-jwt-secret-key-here',\n 'use-different-from-session-secret',\n ],\n }),\n },\n\n SPFN_AUTH_JWT_EXPIRES_IN: {\n ...envString({\n description: 'JWT token expiration time (e.g., \\'7d\\', \\'24h\\', \\'1h\\')',\n default: '7d',\n required: false,\n examples: ['7d', '24h', '1h', '30m'],\n }),\n },\n\n // ============================================================================\n // Security Configuration\n // ============================================================================\n SPFN_AUTH_COOKIE_SECURE: {\n ...envBoolean({\n description: 'Override cookie Secure flag. Defaults to NODE_ENV === \"production\". Set to false for HTTP-only environments (e.g. bastion over plain HTTP).',\n required: false,\n nextjs: true,\n examples: [true, false],\n }),\n },\n\n SPFN_AUTH_BCRYPT_SALT_ROUNDS: {\n ...envNumber({\n description: 'Bcrypt salt rounds (cost factor, higher = more secure but slower)',\n default: 12,\n required: false,\n examples: [10, 12, 14],\n }),\n key: 'SPFN_AUTH_BCRYPT_SALT_ROUNDS',\n },\n\n SPFN_AUTH_VERIFICATION_TOKEN_SECRET: {\n ...envString({\n description: 'Verification token secret for email verification, password reset, etc.',\n required: true,\n examples: [\n 'your-verification-token-secret',\n 'can-be-different-from-jwt-secret',\n ],\n }),\n },\n\n SPFN_AUTH_TOKEN_ENCRYPTION_KEYS: {\n ...envString({\n description: 'Backend-only OAuth token encryption keyring. Comma-separated <keyId>:<base64-encoded 32-byte key> entries; the first key encrypts new values and remaining keys decrypt during rotation.',\n required: false,\n sensitive: true,\n examples: [\n 'v2:<base64-encoded-32-byte-key>,v1:<previous-base64-encoded-32-byte-key>',\n ],\n }),\n },\n\n // ============================================================================\n // Admin Account Configuration\n // ============================================================================\n SPFN_AUTH_ADMIN_ACCOUNTS: {\n ...envString({\n description: 'JSON array of admin accounts (recommended for multiple admins)',\n required: false,\n examples: [\n '[{\"email\":\"admin@example.com\",\"password\":\"secure-pass\",\"role\":\"admin\"}]',\n '[{\"email\":\"super@example.com\",\"password\":\"pass1\",\"role\":\"superadmin\"},{\"email\":\"admin@example.com\",\"password\":\"pass2\",\"role\":\"admin\"}]',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_EMAILS: {\n ...envString({\n description: 'Comma-separated list of admin emails (legacy CSV format)',\n required: false,\n examples: [\n 'admin@example.com,user@example.com',\n 'super@example.com,admin@example.com,user@example.com',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_PASSWORDS: {\n ...envString({\n description: 'Comma-separated list of admin passwords (legacy CSV format)',\n required: false,\n examples: [\n 'admin-pass,user-pass',\n 'super-pass,admin-pass,user-pass',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_ROLES: {\n ...envString({\n description: 'Comma-separated list of admin roles (legacy CSV format)',\n required: false,\n examples: [\n 'admin,user',\n 'superadmin,admin,user',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_EMAIL: {\n ...envString({\n description: 'Single admin email (simplest format)',\n required: false,\n examples: ['admin@example.com'],\n }),\n },\n\n SPFN_AUTH_ADMIN_PASSWORD: {\n ...envString({\n description: 'Single admin password (simplest format)',\n required: false,\n validator: createPasswordParser({\n minLength: 8,\n requireUppercase: true,\n requireLowercase: true,\n requireNumber: true,\n requireSpecial: true,\n }),\n sensitive: true,\n examples: ['SecureAdmin123!'],\n }),\n },\n\n // ============================================================================\n // Username Configuration\n // ============================================================================\n SPFN_AUTH_RESERVED_USERNAMES: {\n ...envString({\n description: 'Comma-separated list of reserved usernames that cannot be registered',\n required: false,\n default: 'admin,root,system,support,help,moderator,superadmin',\n examples: [\n 'admin,root,system,support,help',\n 'admin,root,system,support,help,moderator,superadmin,operator',\n ],\n }),\n },\n\n SPFN_AUTH_USERNAME_MIN_LENGTH: {\n ...envNumber({\n description: 'Minimum username length',\n default: 3,\n required: false,\n examples: [2, 3, 4],\n }),\n },\n\n SPFN_AUTH_USERNAME_MAX_LENGTH: {\n ...envNumber({\n description: 'Maximum username length',\n default: 30,\n required: false,\n examples: [20, 30, 50],\n }),\n },\n\n // ============================================================================\n // API Configuration\n // ============================================================================\n SPFN_API_URL: {\n ...envString({\n description: 'Internal API URL for server-to-server communication',\n default: 'http://localhost:8790',\n required: false,\n examples: [\n 'https://api.example.com',\n 'http://localhost:8790',\n ],\n }),\n },\n\n NEXT_PUBLIC_SPFN_API_URL: {\n ...envString({\n description: 'Public-facing API URL used for browser-facing redirects. Falls back to SPFN_API_URL if not set.',\n required: false,\n examples: [\n 'https://api.example.com',\n 'http://localhost:8790',\n ],\n }),\n },\n\n SPFN_APP_URL: {\n ...envString({\n description: 'Next.js application URL (internal). Used for server-to-server communication.',\n default: 'http://localhost:3000',\n required: false,\n examples: [\n 'https://app.example.com',\n 'http://localhost:3000',\n ],\n }),\n },\n\n NEXT_PUBLIC_SPFN_APP_URL: {\n ...envString({\n description: 'Public-facing Next.js app URL for browser redirects (e.g. OAuth redirect). Falls back to SPFN_APP_URL if not set.',\n required: false,\n examples: [\n 'https://app.example.com',\n 'http://localhost:3000',\n ],\n }),\n },\n\n // ============================================================================\n // OAuth Configuration - Google\n // ============================================================================\n SPFN_AUTH_GOOGLE_CLIENT_ID: {\n ...envString({\n description: 'Google OAuth 2.0 Client ID. When set, Google OAuth routes are automatically enabled.',\n required: false,\n examples: ['123456789-abc123.apps.googleusercontent.com'],\n }),\n },\n\n SPFN_AUTH_GOOGLE_CLIENT_SECRET: {\n ...envString({\n description: 'Google OAuth 2.0 Client Secret',\n required: false,\n sensitive: true,\n examples: ['GOCSPX-abcdefghijklmnop'],\n }),\n },\n\n SPFN_AUTH_GOOGLE_SCOPES: {\n ...envString({\n description: 'Comma-separated Google OAuth scopes. Defaults to \"email,profile\" if not set.',\n required: false,\n examples: [\n 'email,profile',\n 'email,profile,https://www.googleapis.com/auth/gmail.readonly',\n 'email,profile,https://www.googleapis.com/auth/calendar.readonly',\n ],\n }),\n },\n\n SPFN_AUTH_GOOGLE_REDIRECT_URI: {\n ...envString({\n description: 'Google OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/google/callback — the callback must return to the web app origin that set the oauth_csrf cookie (the app rewrites /_auth/:path* to the API). Set this explicitly only when the callback should hit a different host (e.g. the API host for the direct oauthStart flow).',\n required: false,\n examples: [\n 'https://app.example.com/_auth/oauth/google/callback',\n 'http://localhost:3000/_auth/oauth/google/callback',\n ],\n }),\n },\n\n // ============================================================================\n // OAuth Configuration - Kakao\n // ============================================================================\n SPFN_AUTH_KAKAO_CLIENT_ID: {\n ...envString({\n description: 'Kakao Login REST API key. Used as the OAuth client_id.',\n required: false,\n examples: ['your-kakao-rest-api-key'],\n }),\n },\n\n SPFN_AUTH_KAKAO_CLIENT_SECRET: {\n ...envString({\n description: 'Kakao Login client secret. Required when the Kakao client-secret feature is enabled.',\n required: false,\n sensitive: true,\n examples: ['your-kakao-client-secret'],\n }),\n },\n\n SPFN_AUTH_KAKAO_ADMIN_KEY: {\n ...envString({\n description: 'Kakao app admin key. Required to verify the User Unlinked webhook (Authorization: KakaoAK header).',\n required: false,\n sensitive: true,\n examples: ['your-kakao-admin-key'],\n }),\n },\n\n SPFN_AUTH_KAKAO_SCOPES: {\n ...envString({\n description: 'Comma-separated Kakao consent scopes. Defaults to account_email.',\n required: false,\n examples: ['account_email'],\n }),\n },\n\n SPFN_AUTH_KAKAO_REDIRECT_URI: {\n ...envString({\n description: 'Kakao OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/kakao/callback.',\n required: false,\n examples: ['https://app.example.com/_auth/oauth/kakao/callback'],\n }),\n },\n\n // ============================================================================\n // OAuth Configuration - Naver\n // ============================================================================\n SPFN_AUTH_NAVER_CLIENT_ID: {\n ...envString({\n description: 'Naver Login OAuth client ID.',\n required: false,\n examples: ['your-naver-client-id'],\n }),\n },\n\n SPFN_AUTH_NAVER_CLIENT_SECRET: {\n ...envString({\n description: 'Naver Login OAuth client secret.',\n required: false,\n sensitive: true,\n examples: ['your-naver-client-secret'],\n }),\n },\n\n SPFN_AUTH_NAVER_REDIRECT_URI: {\n ...envString({\n description: 'Naver OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/naver/callback.',\n required: false,\n examples: ['https://app.example.com/_auth/oauth/naver/callback'],\n }),\n },\n\n // ============================================================================\n // OAuth Configuration - GitHub\n // ============================================================================\n SPFN_AUTH_GITHUB_CLIENT_ID: {\n ...envString({\n description: 'GitHub OAuth app client ID. When set, GitHub OAuth routes are automatically enabled.',\n required: false,\n examples: ['Iv1.abc123def456'],\n }),\n },\n\n SPFN_AUTH_GITHUB_CLIENT_SECRET: {\n ...envString({\n description: 'GitHub OAuth app client secret.',\n required: false,\n sensitive: true,\n examples: ['your-github-client-secret'],\n }),\n },\n\n SPFN_AUTH_GITHUB_SCOPES: {\n ...envString({\n description: 'Comma-separated GitHub OAuth scopes. Defaults to \"read:user,user:email\".',\n required: false,\n examples: ['read:user,user:email'],\n }),\n },\n\n SPFN_AUTH_GITHUB_REDIRECT_URI: {\n ...envString({\n description: 'GitHub OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/github/callback.',\n required: false,\n examples: ['https://app.example.com/_auth/oauth/github/callback'],\n }),\n },\n\n // ============================================================================\n // Native Social Login (mobile/web id_token verification)\n //\n // 네이티브 SDK가 받은 id_token을 서버가 JWKS로 검증하는 경로 전용 설정.\n // authorization code 교환을 하지 않으므로 client secret이 필요 없다.\n // audience(aud)로 허용할 client id 목록만 지정한다.\n // ============================================================================\n SPFN_AUTH_GOOGLE_NATIVE_CLIENT_IDS: {\n ...envString({\n description: 'Comma-separated Google client IDs accepted as id_token audience for native sign-in (iOS, Android, web). When set, Google native sign-in is enabled. SPFN_AUTH_GOOGLE_CLIENT_ID is also accepted automatically.',\n required: false,\n examples: [\n '123-ios.apps.googleusercontent.com,123-android.apps.googleusercontent.com',\n ],\n }),\n },\n\n SPFN_AUTH_APPLE_CLIENT_IDS: {\n ...envString({\n description: 'Comma-separated Apple client IDs accepted as id_token audience for native sign-in (iOS bundle ID, web/Android Services ID). When set, Apple native sign-in is enabled.',\n required: false,\n examples: [\n 'com.example.app,com.example.app.service',\n ],\n }),\n },\n\n SPFN_AUTH_KAKAO_NATIVE_CLIENT_IDS: {\n ...envString({\n description: 'Comma-separated Kakao app keys accepted as id_token audience for native sign-in (native app key). SPFN_AUTH_KAKAO_CLIENT_ID (REST API key) is also accepted automatically, so native sign-in is available when either variable is set. Requires OpenID Connect to be enabled in the Kakao developer console.',\n required: false,\n examples: [\n 'your-kakao-native-app-key',\n ],\n }),\n },\n\n SPFN_AUTH_NAVER_NATIVE_CLIENT_IDS: {\n ...envString({\n description: 'Comma-separated Naver client IDs accepted as id_token audience for native sign-in. SPFN_AUTH_NAVER_CLIENT_ID is also accepted automatically, and one Naver application has a single client ID covering web and app environments — set this only when the app uses a separate application.',\n required: false,\n examples: [\n 'your-naver-app-client-id',\n ],\n }),\n },\n\n SPFN_AUTH_OAUTH_SUCCESS_URL: {\n ...envString({\n description: 'OAuth callback page URL. This page should use OAuthCallback component to finalize session.',\n required: false,\n default: '/auth/callback',\n examples: [\n '/auth/callback',\n 'https://app.example.com/auth/callback',\n ],\n }),\n },\n\n SPFN_AUTH_OAUTH_ERROR_URL: {\n ...envString({\n description: 'URL to redirect after OAuth error. Use {error} placeholder for error message.',\n required: false,\n default: '/auth/error?error={error}',\n examples: [\n 'https://app.example.com/auth/error?error={error}',\n 'http://localhost:3000/auth/error?error={error}',\n ],\n }),\n },\n});\n"],"mappings":"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","names":[]}
|