@fivepixels-js/lite-api 0.2.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 +93 -0
- package/README.md +537 -0
- package/dist/app.d.ts +10 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +70 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/identity.repository.d.ts +62 -0
- package/dist/auth/identity.repository.d.ts.map +1 -0
- package/dist/auth/identity.repository.js +202 -0
- package/dist/auth/identity.repository.js.map +1 -0
- package/dist/auth/identity.routes.d.ts +5 -0
- package/dist/auth/identity.routes.d.ts.map +1 -0
- package/dist/auth/identity.routes.js +56 -0
- package/dist/auth/identity.routes.js.map +1 -0
- package/dist/auth/identity.schemas.d.ts +2711 -0
- package/dist/auth/identity.schemas.d.ts.map +1 -0
- package/dist/auth/identity.schemas.js +117 -0
- package/dist/auth/identity.schemas.js.map +1 -0
- package/dist/auth/identity.service.d.ts +37 -0
- package/dist/auth/identity.service.d.ts.map +1 -0
- package/dist/auth/identity.service.js +131 -0
- package/dist/auth/identity.service.js.map +1 -0
- package/dist/auth/password.service.d.ts +15 -0
- package/dist/auth/password.service.d.ts.map +1 -0
- package/dist/auth/password.service.js +116 -0
- package/dist/auth/password.service.js.map +1 -0
- package/dist/auth/token.service.d.ts +38 -0
- package/dist/auth/token.service.d.ts.map +1 -0
- package/dist/auth/token.service.js +54 -0
- package/dist/auth/token.service.js.map +1 -0
- package/dist/cli/cli.d.ts +3 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +132 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/commands/backup.d.ts +4 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +24 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/init.d.ts +4 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +23 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +20 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/start.d.ts +4 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +13 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +4 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +48 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/io.d.ts +6 -0
- package/dist/cli/io.d.ts.map +1 -0
- package/dist/cli/io.js +9 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/community/contracts.d.ts +29 -0
- package/dist/community/contracts.d.ts.map +1 -0
- package/dist/community/contracts.js +41 -0
- package/dist/community/contracts.js.map +1 -0
- package/dist/community/error-handler.d.ts +3 -0
- package/dist/community/error-handler.d.ts.map +1 -0
- package/dist/community/error-handler.js +66 -0
- package/dist/community/error-handler.js.map +1 -0
- package/dist/community/errors.d.ts +10 -0
- package/dist/community/errors.d.ts.map +1 -0
- package/dist/community/errors.js +39 -0
- package/dist/community/errors.js.map +1 -0
- package/dist/community/etag.d.ts +5 -0
- package/dist/community/etag.d.ts.map +1 -0
- package/dist/community/etag.js +31 -0
- package/dist/community/etag.js.map +1 -0
- package/dist/community/input.d.ts +10 -0
- package/dist/community/input.d.ts.map +1 -0
- package/dist/community/input.js +48 -0
- package/dist/community/input.js.map +1 -0
- package/dist/community/mutation-route.d.ts +7 -0
- package/dist/community/mutation-route.d.ts.map +1 -0
- package/dist/community/mutation-route.js +47 -0
- package/dist/community/mutation-route.js.map +1 -0
- package/dist/community/schemas.d.ts +807 -0
- package/dist/community/schemas.d.ts.map +1 -0
- package/dist/community/schemas.js +100 -0
- package/dist/community/schemas.js.map +1 -0
- package/dist/community/system.schemas.d.ts +40 -0
- package/dist/community/system.schemas.d.ts.map +1 -0
- package/dist/community/system.schemas.js +30 -0
- package/dist/community/system.schemas.js.map +1 -0
- package/dist/config/config.d.ts +43 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +208 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/data-path.d.ts +2 -0
- package/dist/config/data-path.d.ts.map +1 -0
- package/dist/config/data-path.js +16 -0
- package/dist/config/data-path.js.map +1 -0
- package/dist/config/jwt-secret.d.ts +3 -0
- package/dist/config/jwt-secret.d.ts.map +1 -0
- package/dist/config/jwt-secret.js +67 -0
- package/dist/config/jwt-secret.js.map +1 -0
- package/dist/db/backup.d.ts +10 -0
- package/dist/db/backup.d.ts.map +1 -0
- package/dist/db/backup.js +51 -0
- package/dist/db/backup.js.map +1 -0
- package/dist/db/connection.d.ts +15 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +82 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/guid-order.d.ts +2 -0
- package/dist/db/guid-order.d.ts.map +1 -0
- package/dist/db/guid-order.js +9 -0
- package/dist/db/guid-order.js.map +1 -0
- package/dist/db/migrate.d.ts +37 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +145 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/migrations/001_schema_migrations.sql +6 -0
- package/dist/db/migrations/002_identity.sql +95 -0
- package/dist/db/migrations/003_projects.sql +62 -0
- package/dist/db/migrations/004_feedback_core.sql +236 -0
- package/dist/db/migrations/005_project_member_management.sql +55 -0
- package/dist/db/migrations/006_align_credentials.sql +33 -0
- package/dist/db/migrations/007_align_storage_values.sql +78 -0
- package/dist/db/storage-migration.d.ts +9 -0
- package/dist/db/storage-migration.d.ts.map +1 -0
- package/dist/db/storage-migration.js +79 -0
- package/dist/db/storage-migration.js.map +1 -0
- package/dist/db/transaction.d.ts +9 -0
- package/dist/db/transaction.d.ts.map +1 -0
- package/dist/db/transaction.js +14 -0
- package/dist/db/transaction.js.map +1 -0
- package/dist/errors/error-handler.d.ts +3 -0
- package/dist/errors/error-handler.d.ts.map +1 -0
- package/dist/errors/error-handler.js +50 -0
- package/dist/errors/error-handler.js.map +1 -0
- package/dist/feedbacks/feedback-workflow.service.d.ts +59 -0
- package/dist/feedbacks/feedback-workflow.service.d.ts.map +1 -0
- package/dist/feedbacks/feedback-workflow.service.js +89 -0
- package/dist/feedbacks/feedback-workflow.service.js.map +1 -0
- package/dist/feedbacks/feedback.input.d.ts +4 -0
- package/dist/feedbacks/feedback.input.d.ts.map +1 -0
- package/dist/feedbacks/feedback.input.js +25 -0
- package/dist/feedbacks/feedback.input.js.map +1 -0
- package/dist/feedbacks/feedback.repository.d.ts +48 -0
- package/dist/feedbacks/feedback.repository.d.ts.map +1 -0
- package/dist/feedbacks/feedback.repository.js +238 -0
- package/dist/feedbacks/feedback.repository.js.map +1 -0
- package/dist/feedbacks/feedback.routes.d.ts +4 -0
- package/dist/feedbacks/feedback.routes.d.ts.map +1 -0
- package/dist/feedbacks/feedback.routes.js +78 -0
- package/dist/feedbacks/feedback.routes.js.map +1 -0
- package/dist/feedbacks/feedback.schemas.d.ts +642 -0
- package/dist/feedbacks/feedback.schemas.d.ts.map +1 -0
- package/dist/feedbacks/feedback.schemas.js +131 -0
- package/dist/feedbacks/feedback.schemas.js.map +1 -0
- package/dist/feedbacks/feedback.service.d.ts +23 -0
- package/dist/feedbacks/feedback.service.d.ts.map +1 -0
- package/dist/feedbacks/feedback.service.js +74 -0
- package/dist/feedbacks/feedback.service.js.map +1 -0
- package/dist/feedbacks/feedback.types.d.ts +64 -0
- package/dist/feedbacks/feedback.types.d.ts.map +1 -0
- package/dist/feedbacks/feedback.types.js +2 -0
- package/dist/feedbacks/feedback.types.js.map +1 -0
- package/dist/page-elements/page-element.input.d.ts +7 -0
- package/dist/page-elements/page-element.input.d.ts.map +1 -0
- package/dist/page-elements/page-element.input.js +59 -0
- package/dist/page-elements/page-element.input.js.map +1 -0
- package/dist/page-elements/page-element.repository.d.ts +21 -0
- package/dist/page-elements/page-element.repository.d.ts.map +1 -0
- package/dist/page-elements/page-element.repository.js +123 -0
- package/dist/page-elements/page-element.repository.js.map +1 -0
- package/dist/page-elements/page-element.schemas.d.ts +97 -0
- package/dist/page-elements/page-element.schemas.d.ts.map +1 -0
- package/dist/page-elements/page-element.schemas.js +40 -0
- package/dist/page-elements/page-element.schemas.js.map +1 -0
- package/dist/page-elements/page-element.types.d.ts +24 -0
- package/dist/page-elements/page-element.types.d.ts.map +1 -0
- package/dist/page-elements/page-element.types.js +2 -0
- package/dist/page-elements/page-element.types.js.map +1 -0
- package/dist/plugins/auth.plugin.d.ts +3 -0
- package/dist/plugins/auth.plugin.d.ts.map +1 -0
- package/dist/plugins/auth.plugin.js +28 -0
- package/dist/plugins/auth.plugin.js.map +1 -0
- package/dist/plugins/community-api.plugin.d.ts +5 -0
- package/dist/plugins/community-api.plugin.d.ts.map +1 -0
- package/dist/plugins/community-api.plugin.js +25 -0
- package/dist/plugins/community-api.plugin.js.map +1 -0
- package/dist/plugins/cors.plugin.d.ts +3 -0
- package/dist/plugins/cors.plugin.d.ts.map +1 -0
- package/dist/plugins/cors.plugin.js +19 -0
- package/dist/plugins/cors.plugin.js.map +1 -0
- package/dist/plugins/swagger.plugin.d.ts +3 -0
- package/dist/plugins/swagger.plugin.d.ts.map +1 -0
- package/dist/plugins/swagger.plugin.js +59 -0
- package/dist/plugins/swagger.plugin.js.map +1 -0
- package/dist/plugins/user-auth.plugin.d.ts +33 -0
- package/dist/plugins/user-auth.plugin.d.ts.map +1 -0
- package/dist/plugins/user-auth.plugin.js +62 -0
- package/dist/plugins/user-auth.plugin.js.map +1 -0
- package/dist/projects/members/project-member.repository.d.ts +49 -0
- package/dist/projects/members/project-member.repository.d.ts.map +1 -0
- package/dist/projects/members/project-member.repository.js +215 -0
- package/dist/projects/members/project-member.repository.js.map +1 -0
- package/dist/projects/members/project-member.routes.d.ts +4 -0
- package/dist/projects/members/project-member.routes.d.ts.map +1 -0
- package/dist/projects/members/project-member.routes.js +82 -0
- package/dist/projects/members/project-member.routes.js.map +1 -0
- package/dist/projects/members/project-member.schemas.d.ts +2735 -0
- package/dist/projects/members/project-member.schemas.d.ts.map +1 -0
- package/dist/projects/members/project-member.schemas.js +138 -0
- package/dist/projects/members/project-member.schemas.js.map +1 -0
- package/dist/projects/members/project-member.service.d.ts +29 -0
- package/dist/projects/members/project-member.service.d.ts.map +1 -0
- package/dist/projects/members/project-member.service.js +92 -0
- package/dist/projects/members/project-member.service.js.map +1 -0
- package/dist/projects/project-access.policy.d.ts +11 -0
- package/dist/projects/project-access.policy.d.ts.map +1 -0
- package/dist/projects/project-access.policy.js +30 -0
- package/dist/projects/project-access.policy.js.map +1 -0
- package/dist/projects/project-access.repository.d.ts +12 -0
- package/dist/projects/project-access.repository.d.ts.map +1 -0
- package/dist/projects/project-access.repository.js +45 -0
- package/dist/projects/project-access.repository.js.map +1 -0
- package/dist/projects/project-access.types.d.ts +9 -0
- package/dist/projects/project-access.types.d.ts.map +1 -0
- package/dist/projects/project-access.types.js +2 -0
- package/dist/projects/project-access.types.js.map +1 -0
- package/dist/projects/project-mutation.service.d.ts +15 -0
- package/dist/projects/project-mutation.service.d.ts.map +1 -0
- package/dist/projects/project-mutation.service.js +39 -0
- package/dist/projects/project-mutation.service.js.map +1 -0
- package/dist/projects/project.repository.d.ts +49 -0
- package/dist/projects/project.repository.d.ts.map +1 -0
- package/dist/projects/project.repository.js +155 -0
- package/dist/projects/project.repository.js.map +1 -0
- package/dist/projects/project.routes.d.ts +4 -0
- package/dist/projects/project.routes.d.ts.map +1 -0
- package/dist/projects/project.routes.js +45 -0
- package/dist/projects/project.routes.js.map +1 -0
- package/dist/projects/project.schemas.d.ts +2044 -0
- package/dist/projects/project.schemas.d.ts.map +1 -0
- package/dist/projects/project.schemas.js +90 -0
- package/dist/projects/project.schemas.js.map +1 -0
- package/dist/projects/project.service.d.ts +40 -0
- package/dist/projects/project.service.d.ts.map +1 -0
- package/dist/projects/project.service.js +128 -0
- package/dist/projects/project.service.js.map +1 -0
- package/dist/replies/reply-mutation.service.d.ts +19 -0
- package/dist/replies/reply-mutation.service.d.ts.map +1 -0
- package/dist/replies/reply-mutation.service.js +51 -0
- package/dist/replies/reply-mutation.service.js.map +1 -0
- package/dist/replies/reply.input.d.ts +4 -0
- package/dist/replies/reply.input.d.ts.map +1 -0
- package/dist/replies/reply.input.js +33 -0
- package/dist/replies/reply.input.js.map +1 -0
- package/dist/replies/reply.repository.d.ts +40 -0
- package/dist/replies/reply.repository.d.ts.map +1 -0
- package/dist/replies/reply.repository.js +173 -0
- package/dist/replies/reply.repository.js.map +1 -0
- package/dist/replies/reply.routes.d.ts +4 -0
- package/dist/replies/reply.routes.d.ts.map +1 -0
- package/dist/replies/reply.routes.js +64 -0
- package/dist/replies/reply.routes.js.map +1 -0
- package/dist/replies/reply.schemas.d.ts +251 -0
- package/dist/replies/reply.schemas.d.ts.map +1 -0
- package/dist/replies/reply.schemas.js +51 -0
- package/dist/replies/reply.schemas.js.map +1 -0
- package/dist/replies/reply.service.d.ts +19 -0
- package/dist/replies/reply.service.d.ts.map +1 -0
- package/dist/replies/reply.service.js +50 -0
- package/dist/replies/reply.service.js.map +1 -0
- package/dist/replies/reply.types.d.ts +31 -0
- package/dist/replies/reply.types.d.ts.map +1 -0
- package/dist/replies/reply.types.js +2 -0
- package/dist/replies/reply.types.js.map +1 -0
- package/dist/report-cases/report-case-workflow.service.d.ts +39 -0
- package/dist/report-cases/report-case-workflow.service.d.ts.map +1 -0
- package/dist/report-cases/report-case-workflow.service.js +103 -0
- package/dist/report-cases/report-case-workflow.service.js.map +1 -0
- package/dist/report-cases/report-case.input.d.ts +4 -0
- package/dist/report-cases/report-case.input.d.ts.map +1 -0
- package/dist/report-cases/report-case.input.js +29 -0
- package/dist/report-cases/report-case.input.js.map +1 -0
- package/dist/report-cases/report-case.repository.d.ts +45 -0
- package/dist/report-cases/report-case.repository.d.ts.map +1 -0
- package/dist/report-cases/report-case.repository.js +185 -0
- package/dist/report-cases/report-case.repository.js.map +1 -0
- package/dist/report-cases/report-case.routes.d.ts +4 -0
- package/dist/report-cases/report-case.routes.d.ts.map +1 -0
- package/dist/report-cases/report-case.routes.js +94 -0
- package/dist/report-cases/report-case.routes.js.map +1 -0
- package/dist/report-cases/report-case.schemas.d.ts +294 -0
- package/dist/report-cases/report-case.schemas.d.ts.map +1 -0
- package/dist/report-cases/report-case.schemas.js +77 -0
- package/dist/report-cases/report-case.schemas.js.map +1 -0
- package/dist/report-cases/report-case.service.d.ts +21 -0
- package/dist/report-cases/report-case.service.d.ts.map +1 -0
- package/dist/report-cases/report-case.service.js +60 -0
- package/dist/report-cases/report-case.service.js.map +1 -0
- package/dist/report-cases/report-case.types.d.ts +39 -0
- package/dist/report-cases/report-case.types.d.ts.map +1 -0
- package/dist/report-cases/report-case.types.js +2 -0
- package/dist/report-cases/report-case.types.js.map +1 -0
- package/dist/routes/health.route.d.ts +4 -0
- package/dist/routes/health.route.d.ts.map +1 -0
- package/dist/routes/health.route.js +39 -0
- package/dist/routes/health.route.js.map +1 -0
- package/dist/routes/version.route.d.ts +3 -0
- package/dist/routes/version.route.d.ts.map +1 -0
- package/dist/routes/version.route.js +22 -0
- package/dist/routes/version.route.js.map +1 -0
- package/dist/runtime/index.d.ts +8 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +11 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +66 -0
- package/dist/server.js.map +1 -0
- package/dist/storage/values.d.ts +3 -0
- package/dist/storage/values.d.ts.map +1 -0
- package/dist/storage/values.js +30 -0
- package/dist/storage/values.js.map +1 -0
- package/dist/users/current-user.routes.d.ts +3 -0
- package/dist/users/current-user.routes.d.ts.map +1 -0
- package/dist/users/current-user.routes.js +9 -0
- package/dist/users/current-user.routes.js.map +1 -0
- package/dist/users/current-user.schemas.d.ts +641 -0
- package/dist/users/current-user.schemas.d.ts.map +1 -0
- package/dist/users/current-user.schemas.js +21 -0
- package/dist/users/current-user.schemas.js.map +1 -0
- package/dist/users/user-search.repository.d.ts +19 -0
- package/dist/users/user-search.repository.d.ts.map +1 -0
- package/dist/users/user-search.repository.js +55 -0
- package/dist/users/user-search.repository.js.map +1 -0
- package/dist/users/user-search.routes.d.ts +4 -0
- package/dist/users/user-search.routes.d.ts.map +1 -0
- package/dist/users/user-search.routes.js +19 -0
- package/dist/users/user-search.routes.js.map +1 -0
- package/dist/users/user-search.schemas.d.ts +693 -0
- package/dist/users/user-search.schemas.d.ts.map +1 -0
- package/dist/users/user-search.schemas.js +41 -0
- package/dist/users/user-search.schemas.js.map +1 -0
- package/dist/users/user-search.service.d.ts +20 -0
- package/dist/users/user-search.service.d.ts.map +1 -0
- package/dist/users/user-search.service.js +41 -0
- package/dist/users/user-search.service.js.map +1 -0
- package/dist/users/user.schemas.d.ts +47 -0
- package/dist/users/user.schemas.d.ts.map +1 -0
- package/dist/users/user.schemas.js +13 -0
- package/dist/users/user.schemas.js.map +1 -0
- package/dist/users/user.types.d.ts +6 -0
- package/dist/users/user.types.d.ts.map +1 -0
- package/dist/users/user.types.js +2 -0
- package/dist/users/user.types.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/docs/guides/community-api-quickstart.md +171 -0
- package/docs/guides/feature-structure.md +138 -0
- package/docs/guides/independent-cli.md +73 -0
- package/docs/guides/non-attachment-api-contract.md +138 -0
- package/docs/plans/selfdev-schema-alignment.md +61 -0
- package/package.json +76 -0
- package/sql/fivepixels-lite-init.sql +518 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.schemas.d.ts","sourceRoot":"","sources":["../../src/auth/identity.schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { communityErrorResponses, communityResponseSchema, nullableStringSchema, uuidSchema, } from '../community/schemas.js';
|
|
2
|
+
export const dateTimeSchema = { type: 'string', format: 'date-time' };
|
|
3
|
+
export const authenticationUserSchema = {
|
|
4
|
+
type: 'object',
|
|
5
|
+
additionalProperties: false,
|
|
6
|
+
required: ['id', 'loginId', 'userName', 'profileImageUrl'],
|
|
7
|
+
properties: {
|
|
8
|
+
id: uuidSchema,
|
|
9
|
+
loginId: { type: 'string' },
|
|
10
|
+
userName: { type: 'string' },
|
|
11
|
+
profileImageUrl: nullableStringSchema,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export const tokenResponseSchema = {
|
|
15
|
+
type: 'object',
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
required: [
|
|
18
|
+
'accessToken',
|
|
19
|
+
'tokenType',
|
|
20
|
+
'accessTokenExpiresAt',
|
|
21
|
+
'refreshToken',
|
|
22
|
+
'refreshTokenExpiresAt',
|
|
23
|
+
'user',
|
|
24
|
+
],
|
|
25
|
+
properties: {
|
|
26
|
+
accessToken: { type: 'string', minLength: 1 },
|
|
27
|
+
tokenType: { type: 'string', const: 'Bearer' },
|
|
28
|
+
accessTokenExpiresAt: dateTimeSchema,
|
|
29
|
+
refreshToken: { type: 'string', minLength: 1, maxLength: 512 },
|
|
30
|
+
refreshTokenExpiresAt: dateTimeSchema,
|
|
31
|
+
user: authenticationUserSchema,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
export const registerRouteSchema = {
|
|
35
|
+
tags: ['auth'],
|
|
36
|
+
summary: '로컬 계정 회원가입',
|
|
37
|
+
body: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
additionalProperties: false,
|
|
40
|
+
required: ['loginId', 'email', 'password', 'userName'],
|
|
41
|
+
properties: {
|
|
42
|
+
loginId: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
minLength: 4,
|
|
45
|
+
maxLength: 50,
|
|
46
|
+
pattern: '^[A-Za-z0-9][A-Za-z0-9._-]{3,49}$',
|
|
47
|
+
},
|
|
48
|
+
email: { type: 'string', format: 'email', minLength: 3, maxLength: 320 },
|
|
49
|
+
password: { type: 'string', minLength: 8, maxLength: 256 },
|
|
50
|
+
userName: { type: 'string', minLength: 1, maxLength: 100 },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
response: {
|
|
54
|
+
201: communityResponseSchema({
|
|
55
|
+
type: 'object',
|
|
56
|
+
additionalProperties: false,
|
|
57
|
+
required: ['id', 'loginId', 'email', 'userName', 'createdAt'],
|
|
58
|
+
properties: {
|
|
59
|
+
id: uuidSchema,
|
|
60
|
+
loginId: { type: 'string' },
|
|
61
|
+
email: { type: 'string' },
|
|
62
|
+
userName: { type: 'string' },
|
|
63
|
+
createdAt: dateTimeSchema,
|
|
64
|
+
},
|
|
65
|
+
}),
|
|
66
|
+
...communityErrorResponses,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
export const loginRouteSchema = {
|
|
70
|
+
tags: ['auth'],
|
|
71
|
+
summary: '로컬 계정 로그인',
|
|
72
|
+
body: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
additionalProperties: false,
|
|
75
|
+
required: ['loginId', 'password'],
|
|
76
|
+
properties: {
|
|
77
|
+
loginId: { type: 'string', minLength: 4, maxLength: 50 },
|
|
78
|
+
password: { type: 'string', minLength: 1, maxLength: 256 },
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
response: {
|
|
82
|
+
200: communityResponseSchema(tokenResponseSchema),
|
|
83
|
+
...communityErrorResponses,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
export const refreshTokenBodySchema = {
|
|
87
|
+
type: 'object',
|
|
88
|
+
additionalProperties: false,
|
|
89
|
+
required: ['refreshToken'],
|
|
90
|
+
properties: {
|
|
91
|
+
refreshToken: { type: 'string', minLength: 1, maxLength: 512 },
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
export const refreshRouteSchema = {
|
|
95
|
+
tags: ['auth'],
|
|
96
|
+
summary: 'Access Token 및 Refresh Token 갱신',
|
|
97
|
+
body: refreshTokenBodySchema,
|
|
98
|
+
response: {
|
|
99
|
+
200: communityResponseSchema(tokenResponseSchema),
|
|
100
|
+
...communityErrorResponses,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
export const logoutRouteSchema = {
|
|
104
|
+
tags: ['auth'],
|
|
105
|
+
summary: 'Refresh Token 로그아웃',
|
|
106
|
+
body: refreshTokenBodySchema,
|
|
107
|
+
response: {
|
|
108
|
+
200: communityResponseSchema({
|
|
109
|
+
type: 'object',
|
|
110
|
+
additionalProperties: false,
|
|
111
|
+
required: ['loggedOut'],
|
|
112
|
+
properties: { loggedOut: { type: 'boolean', const: true } },
|
|
113
|
+
}),
|
|
114
|
+
...communityErrorResponses,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
//# sourceMappingURL=identity.schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.schemas.js","sourceRoot":"","sources":["../../src/auth/identity.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,UAAU,GACX,MAAM,yBAAyB,CAAC;AAEjC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAW,CAAC;AAE/E,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,CAAC;IAC1D,UAAU,EAAE;QACV,EAAE,EAAE,UAAU;QACd,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC3B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,eAAe,EAAE,oBAAoB;KACtC;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE;QACR,aAAa;QACb,WAAW;QACX,sBAAsB;QACtB,cAAc;QACd,uBAAuB;QACvB,MAAM;KACP;IACD,UAAU,EAAE;QACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE;QAC7C,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;QAC9C,oBAAoB,EAAE,cAAc;QACpC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;QAC9D,qBAAqB,EAAE,cAAc;QACrC,IAAI,EAAE,wBAAwB;KAC/B;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,OAAO,EAAE,YAAY;IACrB,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,oBAAoB,EAAE,KAAK;QAC3B,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC;QACtD,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,CAAC;gBACZ,SAAS,EAAE,EAAE;gBACb,OAAO,EAAE,mCAAmC;aAC7C;YACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;YACxE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;YAC1D,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;SAC3D;KACF;IACD,QAAQ,EAAE;QACR,GAAG,EAAE,uBAAuB,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,oBAAoB,EAAE,KAAK;YAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,CAAC;YAC7D,UAAU,EAAE;gBACV,EAAE,EAAE,UAAU;gBACd,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC3B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC5B,SAAS,EAAE,cAAc;aAC1B;SACF,CAAC;QACF,GAAG,uBAAuB;KAC3B;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,OAAO,EAAE,WAAW;IACpB,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,oBAAoB,EAAE,KAAK;QAC3B,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;QACjC,UAAU,EAAE;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;YACxD,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;SAC3D;KACF;IACD,QAAQ,EAAE;QACR,GAAG,EAAE,uBAAuB,CAAC,mBAAmB,CAAC;QACjD,GAAG,uBAAuB;KAC3B;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,CAAC,cAAc,CAAC;IAC1B,UAAU,EAAE;QACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;KAC/D;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,OAAO,EAAE,iCAAiC;IAC1C,IAAI,EAAE,sBAAsB;IAC5B,QAAQ,EAAE;QACR,GAAG,EAAE,uBAAuB,CAAC,mBAAmB,CAAC;QACjD,GAAG,uBAAuB;KAC3B;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,OAAO,EAAE,oBAAoB;IAC7B,IAAI,EAAE,sBAAsB;IAC5B,QAAQ,EAAE;QACR,GAAG,EAAE,uBAAuB,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,oBAAoB,EAAE,KAAK;YAC3B,QAAQ,EAAE,CAAC,WAAW,CAAC;YACvB,UAAU,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;SAC5D,CAAC;QACF,GAAG,uBAAuB;KAC3B;CACO,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AppConfig } from '../config/config.js';
|
|
2
|
+
import type { IdentityRepository } from './identity.repository.js';
|
|
3
|
+
import type { PasswordService } from './password.service.js';
|
|
4
|
+
import type { TokenResponse, TokenService } from './token.service.js';
|
|
5
|
+
export interface RegisterRequest {
|
|
6
|
+
email: string;
|
|
7
|
+
loginId: string;
|
|
8
|
+
password: string;
|
|
9
|
+
userName: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RegisterResponse {
|
|
12
|
+
createdAt: string;
|
|
13
|
+
email: string;
|
|
14
|
+
id: string;
|
|
15
|
+
loginId: string;
|
|
16
|
+
userName: string;
|
|
17
|
+
}
|
|
18
|
+
export interface LoginRequest {
|
|
19
|
+
loginId: string;
|
|
20
|
+
password: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class IdentityService {
|
|
23
|
+
private readonly repository;
|
|
24
|
+
private readonly passwordService;
|
|
25
|
+
private readonly tokenService;
|
|
26
|
+
private readonly config;
|
|
27
|
+
private readonly now;
|
|
28
|
+
constructor(repository: IdentityRepository, passwordService: PasswordService, tokenService: TokenService, config: AppConfig, now?: () => Date);
|
|
29
|
+
register(request: RegisterRequest): Promise<RegisterResponse>;
|
|
30
|
+
login(request: LoginRequest): Promise<TokenResponse>;
|
|
31
|
+
refresh(refreshTokenValue: string): TokenResponse;
|
|
32
|
+
logout(refreshTokenValue: string): {
|
|
33
|
+
loggedOut: true;
|
|
34
|
+
};
|
|
35
|
+
private authenticationUser;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=identity.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.service.d.ts","sourceRoot":"","sources":["../../src/auth/identity.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAA4B,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwBD,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAJH,UAAU,EAAE,kBAAkB,EAC9B,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,SAAS,EACjB,GAAG,GAAE,MAAM,IAAuB;IAGxC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyC7D,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAwE1D,OAAO,CAAC,iBAAiB,EAAE,MAAM,GAAG,aAAa;IAsBjD,MAAM,CAAC,iBAAiB,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,IAAI,CAAA;KAAE;IAK7D,OAAO,CAAC,kBAAkB;CAQ3B"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { CommunityApiError } from '../community/errors.js';
|
|
3
|
+
import { storageTimestamp } from '../storage/values.js';
|
|
4
|
+
function isUniqueConstraint(error) {
|
|
5
|
+
if (typeof error !== 'object' || error === null || !('code' in error))
|
|
6
|
+
return false;
|
|
7
|
+
const code = error.code;
|
|
8
|
+
return code === 'SQLITE_CONSTRAINT_UNIQUE' || code === 'SQLITE_CONSTRAINT_PRIMARYKEY';
|
|
9
|
+
}
|
|
10
|
+
function invalidCredentials() {
|
|
11
|
+
return new CommunityApiError(401, 'invalid-credentials', '아이디 또는 비밀번호가 올바르지 않습니다.');
|
|
12
|
+
}
|
|
13
|
+
function invalidRefreshToken() {
|
|
14
|
+
return new CommunityApiError(401, 'invalid-refresh-token', 'Refresh Token이 유효하지 않거나 만료되었습니다.');
|
|
15
|
+
}
|
|
16
|
+
export class IdentityService {
|
|
17
|
+
repository;
|
|
18
|
+
passwordService;
|
|
19
|
+
tokenService;
|
|
20
|
+
config;
|
|
21
|
+
now;
|
|
22
|
+
constructor(repository, passwordService, tokenService, config, now = () => new Date()) {
|
|
23
|
+
this.repository = repository;
|
|
24
|
+
this.passwordService = passwordService;
|
|
25
|
+
this.tokenService = tokenService;
|
|
26
|
+
this.config = config;
|
|
27
|
+
this.now = now;
|
|
28
|
+
}
|
|
29
|
+
async register(request) {
|
|
30
|
+
if (!this.config.registrationEnabled) {
|
|
31
|
+
throw new CommunityApiError(403, 'registration-disabled', '현재 서버에서는 회원가입을 사용할 수 없습니다.');
|
|
32
|
+
}
|
|
33
|
+
const loginId = request.loginId.trim();
|
|
34
|
+
const email = request.email.trim().toLowerCase();
|
|
35
|
+
const userName = request.userName.trim();
|
|
36
|
+
if (loginId === '' || email === '' || userName === '') {
|
|
37
|
+
throw new CommunityApiError(400, 'invalid-registration', '회원가입 입력값을 확인해 주세요.');
|
|
38
|
+
}
|
|
39
|
+
const createdAt = storageTimestamp(this.now());
|
|
40
|
+
const passwordHash = await this.passwordService.hash(request.password);
|
|
41
|
+
const result = { id: randomUUID(), loginId, email, userName, createdAt };
|
|
42
|
+
try {
|
|
43
|
+
this.repository.registerAccount({
|
|
44
|
+
...result,
|
|
45
|
+
passwordHash,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (isUniqueConstraint(error)) {
|
|
50
|
+
throw new CommunityApiError(409, 'account-already-exists', '이미 사용 중인 로그인 ID 또는 이메일입니다.');
|
|
51
|
+
}
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
async login(request) {
|
|
57
|
+
const loginId = request.loginId.trim();
|
|
58
|
+
const credential = this.repository.findCredentialByLoginId(loginId);
|
|
59
|
+
if (credential === undefined) {
|
|
60
|
+
await this.passwordService.verifyDummy(request.password);
|
|
61
|
+
throw invalidCredentials();
|
|
62
|
+
}
|
|
63
|
+
const requestedAt = this.now();
|
|
64
|
+
if (credential.lockedUntil !== null && credential.lockedUntil > storageTimestamp(requestedAt)) {
|
|
65
|
+
throw new CommunityApiError(423, 'account-locked', '로그인 시도 횟수를 초과했습니다. 잠시 후 다시 시도해 주세요.');
|
|
66
|
+
}
|
|
67
|
+
const verification = await this.passwordService.verifyForLogin(credential.passwordHash, request.password);
|
|
68
|
+
const now = this.now();
|
|
69
|
+
const currentCredential = this.repository.findCredentialByLoginId(loginId);
|
|
70
|
+
if (currentCredential === undefined || currentCredential.passwordHash !== credential.passwordHash) {
|
|
71
|
+
throw invalidCredentials();
|
|
72
|
+
}
|
|
73
|
+
if (currentCredential.lockedUntil !== null && currentCredential.lockedUntil > storageTimestamp(now)) {
|
|
74
|
+
throw new CommunityApiError(423, 'account-locked', '로그인 시도 횟수를 초과했습니다. 잠시 후 다시 시도해 주세요.');
|
|
75
|
+
}
|
|
76
|
+
if (!verification.valid) {
|
|
77
|
+
const lockedUntil = storageTimestamp(new Date(now.getTime() + this.config.lockoutMinutes * 60_000));
|
|
78
|
+
this.repository.recordFailedLogin(currentCredential.id, storageTimestamp(now), lockedUntil, this.config.maxFailedLoginAttempts);
|
|
79
|
+
throw invalidCredentials();
|
|
80
|
+
}
|
|
81
|
+
if (currentCredential.statusCode !== 1) {
|
|
82
|
+
throw new CommunityApiError(403, 'user-blocked', '사용할 수 없는 Fivepixels 사용자입니다.');
|
|
83
|
+
}
|
|
84
|
+
const replacementHash = verification.needsRehash
|
|
85
|
+
? await this.passwordService.hash(request.password) : undefined;
|
|
86
|
+
// Hashing yields. Re-read lockout/status and CAS the latest observed version below.
|
|
87
|
+
const latest = this.repository.findCredentialByLoginId(loginId);
|
|
88
|
+
if (latest === undefined || latest.passwordHash !== credential.passwordHash)
|
|
89
|
+
throw invalidCredentials();
|
|
90
|
+
const loginTime = this.now();
|
|
91
|
+
const completedAt = storageTimestamp(loginTime);
|
|
92
|
+
if (latest.lockedUntil !== null && latest.lockedUntil > completedAt) {
|
|
93
|
+
throw new CommunityApiError(423, 'account-locked', '로그인 시도 횟수를 초과했습니다. 잠시 후 다시 시도해 주세요.');
|
|
94
|
+
}
|
|
95
|
+
if (latest.statusCode !== 1) {
|
|
96
|
+
throw new CommunityApiError(403, 'user-blocked', '사용할 수 없는 Fivepixels 사용자입니다.');
|
|
97
|
+
}
|
|
98
|
+
const user = this.authenticationUser(latest);
|
|
99
|
+
const refreshToken = this.tokenService.createRefreshToken(loginTime);
|
|
100
|
+
const response = this.tokenService.createTokenResponse(user, refreshToken, loginTime);
|
|
101
|
+
if (!this.repository.completeLogin(latest, completedAt, refreshToken.database, replacementHash)) {
|
|
102
|
+
throw invalidCredentials();
|
|
103
|
+
}
|
|
104
|
+
return response;
|
|
105
|
+
}
|
|
106
|
+
refresh(refreshTokenValue) {
|
|
107
|
+
const now = this.now();
|
|
108
|
+
const tokenHash = this.tokenService.hashRefreshToken(refreshTokenValue);
|
|
109
|
+
const replacement = this.tokenService.createRefreshToken(now);
|
|
110
|
+
const storedToken = this.repository.rotateRefreshToken(tokenHash, replacement.database, storageTimestamp(now));
|
|
111
|
+
if (storedToken.kind === 'invalid')
|
|
112
|
+
throw invalidRefreshToken();
|
|
113
|
+
if (storedToken.kind === 'user-blocked') {
|
|
114
|
+
throw new CommunityApiError(403, 'user-blocked', '사용할 수 없는 Fivepixels 사용자입니다.');
|
|
115
|
+
}
|
|
116
|
+
return this.tokenService.createTokenResponse(storedToken.user, replacement, now);
|
|
117
|
+
}
|
|
118
|
+
logout(refreshTokenValue) {
|
|
119
|
+
this.repository.logout(this.tokenService.hashRefreshToken(refreshTokenValue), storageTimestamp(this.now()));
|
|
120
|
+
return { loggedOut: true };
|
|
121
|
+
}
|
|
122
|
+
authenticationUser(credential) {
|
|
123
|
+
return {
|
|
124
|
+
id: credential.id,
|
|
125
|
+
loginId: credential.loginId,
|
|
126
|
+
userName: credential.userName,
|
|
127
|
+
profileImageUrl: credential.profileImageUrl,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=identity.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.service.js","sourceRoot":"","sources":["../../src/auth/identity.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface PasswordVerification {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
needsRehash: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare class PasswordService {
|
|
6
|
+
private activeHashes;
|
|
7
|
+
private readonly queue;
|
|
8
|
+
hash(password: string): Promise<string>;
|
|
9
|
+
verify(encoded: string, password: string): Promise<boolean>;
|
|
10
|
+
verifyForLogin(encoded: string, password: string): Promise<PasswordVerification>;
|
|
11
|
+
verifyDummy(password: string): Promise<void>;
|
|
12
|
+
private derive;
|
|
13
|
+
private execute;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=password.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.service.d.ts","sourceRoot":"","sources":["../../src/auth/password.service.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAqCD,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IAE1B,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWvC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI3D,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAWhF,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOzD,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,OAAO;CAoBhB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { pbkdf2, randomBytes, scrypt, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { CommunityApiError } from '../community/errors.js';
|
|
3
|
+
const ITERATIONS = 600_000;
|
|
4
|
+
const MAX_ITERATIONS = 1_000_000;
|
|
5
|
+
const MAX_CONCURRENT_HASHES = 1;
|
|
6
|
+
const MAX_QUEUED_HASHES = 16;
|
|
7
|
+
function decode(encoded, encoding) {
|
|
8
|
+
const bytes = Buffer.from(encoded, encoding);
|
|
9
|
+
return bytes.toString(encoding) === encoded ? bytes : undefined;
|
|
10
|
+
}
|
|
11
|
+
function parse(encoded) {
|
|
12
|
+
if (encoded.length > 512)
|
|
13
|
+
return undefined;
|
|
14
|
+
if (encoded.startsWith('$scrypt$')) {
|
|
15
|
+
const parts = encoded.split('$');
|
|
16
|
+
if (parts.length !== 6 || parts[2] !== 'v=1' || parts[3] !== 'n=32768,r=8,p=3')
|
|
17
|
+
return undefined;
|
|
18
|
+
const salt = decode(parts[4] ?? '', 'base64url');
|
|
19
|
+
const hash = decode(parts[5] ?? '', 'base64url');
|
|
20
|
+
if (salt?.length !== 16 || hash?.length !== 32)
|
|
21
|
+
return undefined;
|
|
22
|
+
return { algorithm: 'scrypt', iterations: 0, length: 32, salt, hash, rehash: true };
|
|
23
|
+
}
|
|
24
|
+
const bytes = decode(encoded, 'base64');
|
|
25
|
+
if (bytes === undefined)
|
|
26
|
+
return undefined;
|
|
27
|
+
if (bytes[0] === 0 && bytes.length === 49) {
|
|
28
|
+
return { algorithm: 'sha1', iterations: 1_000, length: 32,
|
|
29
|
+
salt: bytes.subarray(1, 17), hash: bytes.subarray(17), rehash: true };
|
|
30
|
+
}
|
|
31
|
+
if (bytes[0] !== 1 || bytes.length < 13)
|
|
32
|
+
return undefined;
|
|
33
|
+
const prf = bytes.readUInt32BE(1);
|
|
34
|
+
const iterations = bytes.readUInt32BE(5);
|
|
35
|
+
const saltLength = bytes.readUInt32BE(9);
|
|
36
|
+
const length = bytes.length - 13 - saltLength;
|
|
37
|
+
const algorithm = ['sha1', 'sha256', 'sha512'][prf];
|
|
38
|
+
if (algorithm === undefined || iterations < 1 || iterations > MAX_ITERATIONS
|
|
39
|
+
|| saltLength < 16 || saltLength > 64 || length < 16 || length > 64)
|
|
40
|
+
return undefined;
|
|
41
|
+
return { algorithm, iterations, length, salt: bytes.subarray(13, 13 + saltLength),
|
|
42
|
+
hash: bytes.subarray(13 + saltLength),
|
|
43
|
+
rehash: length < 32 || algorithm === 'sha1' || (algorithm === 'sha256' && iterations < ITERATIONS)
|
|
44
|
+
|| (algorithm === 'sha512' && iterations < 210_000) };
|
|
45
|
+
}
|
|
46
|
+
export class PasswordService {
|
|
47
|
+
activeHashes = 0;
|
|
48
|
+
queue = [];
|
|
49
|
+
async hash(password) {
|
|
50
|
+
const salt = randomBytes(16);
|
|
51
|
+
const hash = await this.derive(password, { algorithm: 'sha256', iterations: ITERATIONS, length: 32, salt });
|
|
52
|
+
const header = Buffer.alloc(13);
|
|
53
|
+
header[0] = 1;
|
|
54
|
+
header.writeUInt32BE(1, 1);
|
|
55
|
+
header.writeUInt32BE(ITERATIONS, 5);
|
|
56
|
+
header.writeUInt32BE(salt.length, 9);
|
|
57
|
+
return Buffer.concat([header, salt, hash]).toString('base64');
|
|
58
|
+
}
|
|
59
|
+
async verify(encoded, password) {
|
|
60
|
+
return (await this.verifyForLogin(encoded, password)).valid;
|
|
61
|
+
}
|
|
62
|
+
async verifyForLogin(encoded, password) {
|
|
63
|
+
const parsed = parse(encoded);
|
|
64
|
+
if (parsed === undefined) {
|
|
65
|
+
await this.verifyDummy(password);
|
|
66
|
+
return { valid: false, needsRehash: false };
|
|
67
|
+
}
|
|
68
|
+
const actual = await this.derive(password, parsed);
|
|
69
|
+
const valid = timingSafeEqual(actual, parsed.hash);
|
|
70
|
+
return { valid, needsRehash: valid && parsed.rehash };
|
|
71
|
+
}
|
|
72
|
+
async verifyDummy(password) {
|
|
73
|
+
const actual = await this.derive(password, {
|
|
74
|
+
algorithm: 'sha256', iterations: ITERATIONS, length: 32, salt: Buffer.alloc(16, 0x5a),
|
|
75
|
+
});
|
|
76
|
+
timingSafeEqual(actual, Buffer.alloc(32));
|
|
77
|
+
}
|
|
78
|
+
derive(password, input) {
|
|
79
|
+
if (this.activeHashes >= MAX_CONCURRENT_HASHES && this.queue.length >= MAX_QUEUED_HASHES) {
|
|
80
|
+
return Promise.reject(new CommunityApiError(503, 'authentication-busy', '인증 요청이 많습니다. 잠시 후 다시 시도해 주세요.'));
|
|
81
|
+
}
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const job = { password, input, resolve, reject };
|
|
84
|
+
if (this.activeHashes < MAX_CONCURRENT_HASHES)
|
|
85
|
+
this.execute(job);
|
|
86
|
+
else
|
|
87
|
+
this.queue.push(job);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
execute(job) {
|
|
91
|
+
this.activeHashes++;
|
|
92
|
+
const done = (error, key) => {
|
|
93
|
+
this.activeHashes--;
|
|
94
|
+
if (error === null)
|
|
95
|
+
job.resolve(key);
|
|
96
|
+
else
|
|
97
|
+
job.reject(error);
|
|
98
|
+
const next = this.queue.shift();
|
|
99
|
+
if (next !== undefined)
|
|
100
|
+
this.execute(next);
|
|
101
|
+
};
|
|
102
|
+
try {
|
|
103
|
+
const input = job.input;
|
|
104
|
+
if (input.algorithm === 'scrypt') {
|
|
105
|
+
scrypt(job.password, input.salt, input.length, { N: 32_768, r: 8, p: 3, maxmem: 64 * 1024 * 1024 }, done);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
pbkdf2(job.password, input.salt, input.iterations, input.length, input.algorithm, done);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
done(error instanceof Error ? error : new Error('password-derivation-failed'), Buffer.alloc(0));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=password.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.service.js","sourceRoot":"","sources":["../../src/auth/password.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AppConfig } from '../config/config.js';
|
|
2
|
+
import type { AuthenticationUserRecord, NewRefreshTokenInput } from './identity.repository.js';
|
|
3
|
+
export interface AccessTokenPayload {
|
|
4
|
+
fivepixels_user_id: string;
|
|
5
|
+
iat: number;
|
|
6
|
+
jti: string;
|
|
7
|
+
name: string;
|
|
8
|
+
sub: string;
|
|
9
|
+
token_scope: 'fivepixels_access';
|
|
10
|
+
}
|
|
11
|
+
export interface TokenResponse {
|
|
12
|
+
accessToken: string;
|
|
13
|
+
accessTokenExpiresAt: string;
|
|
14
|
+
refreshToken: string;
|
|
15
|
+
refreshTokenExpiresAt: string;
|
|
16
|
+
tokenType: 'Bearer';
|
|
17
|
+
user: AuthenticationUserRecord;
|
|
18
|
+
}
|
|
19
|
+
export interface RefreshTokenMaterial {
|
|
20
|
+
database: NewRefreshTokenInput;
|
|
21
|
+
value: string;
|
|
22
|
+
}
|
|
23
|
+
export type AccessTokenSigner = (payload: AccessTokenPayload, options: {
|
|
24
|
+
algorithm: 'HS256';
|
|
25
|
+
aud: string;
|
|
26
|
+
expiresIn: number;
|
|
27
|
+
iss: string;
|
|
28
|
+
notBefore: number;
|
|
29
|
+
}) => string;
|
|
30
|
+
export declare class TokenService {
|
|
31
|
+
private readonly config;
|
|
32
|
+
private readonly sign;
|
|
33
|
+
constructor(config: AppConfig, sign: AccessTokenSigner);
|
|
34
|
+
createRefreshToken(issuedAt: Date): RefreshTokenMaterial;
|
|
35
|
+
createTokenResponse(user: AuthenticationUserRecord, refreshToken: RefreshTokenMaterial, issuedAt: Date): TokenResponse;
|
|
36
|
+
hashRefreshToken(refreshToken: string): Buffer;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=token.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.service.d.ts","sourceRoot":"","sources":["../../src/auth/token.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAE/F,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,mBAAmB,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,SAAS,EAAE,QAAQ,CAAC;IACpB,IAAI,EAAE,wBAAwB,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE;IACP,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB,KACE,MAAM,CAAC;AAEZ,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBADJ,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,iBAAiB;IAGnC,kBAAkB,CAAC,QAAQ,EAAE,IAAI,GAAG,oBAAoB;IAexD,mBAAmB,CACxB,IAAI,EAAE,wBAAwB,EAC9B,YAAY,EAAE,oBAAoB,EAClC,QAAQ,EAAE,IAAI,GACb,aAAa;IA6BT,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;CAGtD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createHash, randomBytes, randomUUID } from 'node:crypto';
|
|
2
|
+
import { storageTimestamp } from '../storage/values.js';
|
|
3
|
+
export class TokenService {
|
|
4
|
+
config;
|
|
5
|
+
sign;
|
|
6
|
+
constructor(config, sign) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
this.sign = sign;
|
|
9
|
+
}
|
|
10
|
+
createRefreshToken(issuedAt) {
|
|
11
|
+
const value = randomBytes(64).toString('base64url');
|
|
12
|
+
const expiresAt = new Date(issuedAt.getTime());
|
|
13
|
+
expiresAt.setUTCDate(expiresAt.getUTCDate() + this.config.refreshTokenExpirationDays);
|
|
14
|
+
return {
|
|
15
|
+
value,
|
|
16
|
+
database: {
|
|
17
|
+
id: randomUUID(),
|
|
18
|
+
tokenHash: this.hashRefreshToken(value),
|
|
19
|
+
createdAt: storageTimestamp(issuedAt),
|
|
20
|
+
expiresAt: storageTimestamp(expiresAt),
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
createTokenResponse(user, refreshToken, issuedAt) {
|
|
25
|
+
const accessTokenExpiresAt = new Date(issuedAt.getTime() + this.config.accessTokenExpirationMinutes * 60_000);
|
|
26
|
+
const payload = {
|
|
27
|
+
sub: user.id,
|
|
28
|
+
name: user.userName,
|
|
29
|
+
fivepixels_user_id: user.id,
|
|
30
|
+
token_scope: 'fivepixels_access',
|
|
31
|
+
jti: randomUUID(),
|
|
32
|
+
iat: Math.floor(issuedAt.getTime() / 1000),
|
|
33
|
+
};
|
|
34
|
+
const accessToken = this.sign(payload, {
|
|
35
|
+
algorithm: 'HS256',
|
|
36
|
+
aud: this.config.jwtAudience,
|
|
37
|
+
expiresIn: this.config.accessTokenExpirationMinutes * 60,
|
|
38
|
+
iss: this.config.jwtIssuer,
|
|
39
|
+
notBefore: 0,
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
accessToken,
|
|
43
|
+
tokenType: 'Bearer',
|
|
44
|
+
accessTokenExpiresAt: storageTimestamp(accessTokenExpiresAt),
|
|
45
|
+
refreshToken: refreshToken.value,
|
|
46
|
+
refreshTokenExpiresAt: refreshToken.database.expiresAt,
|
|
47
|
+
user,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
hashRefreshToken(refreshToken) {
|
|
51
|
+
return createHash('sha256').update(refreshToken).digest();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=token.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.service.js","sourceRoot":"","sources":["../../src/auth/token.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAqCxD,MAAM,OAAO,YAAY;IAEJ;IACA;IAFnB,YACmB,MAAiB,EACjB,IAAuB;QADvB,WAAM,GAAN,MAAM,CAAW;QACjB,SAAI,GAAJ,IAAI,CAAmB;IACvC,CAAC;IAEG,kBAAkB,CAAC,QAAc;QACtC,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC;QACtF,OAAO;YACL,KAAK;YACL,QAAQ,EAAE;gBACR,EAAE,EAAE,UAAU,EAAE;gBAChB,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;gBACvC,SAAS,EAAE,gBAAgB,CAAC,QAAQ,CAAC;gBACrC,SAAS,EAAE,gBAAgB,CAAC,SAAS,CAAC;aACvC;SACF,CAAC;IACJ,CAAC;IAEM,mBAAmB,CACxB,IAA8B,EAC9B,YAAkC,EAClC,QAAc;QAEd,MAAM,oBAAoB,GAAG,IAAI,IAAI,CACnC,QAAQ,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,4BAA4B,GAAG,MAAM,CACvE,CAAC;QACF,MAAM,OAAO,GAAuB;YAClC,GAAG,EAAE,IAAI,CAAC,EAAE;YACZ,IAAI,EAAE,IAAI,CAAC,QAAQ;YACnB,kBAAkB,EAAE,IAAI,CAAC,EAAE;YAC3B,WAAW,EAAE,mBAAmB;YAChC,GAAG,EAAE,UAAU,EAAE;YACjB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;SAC3C,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACrC,SAAS,EAAE,OAAO;YAClB,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;YAC5B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,4BAA4B,GAAG,EAAE;YACxD,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAC1B,SAAS,EAAE,CAAC;SACb,CAAC,CAAC;QACH,OAAO;YACL,WAAW;YACX,SAAS,EAAE,QAAQ;YACnB,oBAAoB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;YAC5D,YAAY,EAAE,YAAY,CAAC,KAAK;YAChC,qBAAqB,EAAE,YAAY,CAAC,QAAQ,CAAC,SAAS;YACtD,IAAI;SACL,CAAC;IACJ,CAAC;IAEM,gBAAgB,CAAC,YAAoB;QAC1C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5D,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":"AASA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAqDpD,wBAAsB,MAAM,CAC1B,UAAU,EAAE,MAAM,EAAE,EACpB,WAAW,GAAE,MAAM,CAAC,UAAwB,EAC5C,EAAE,GAAE,SAAqB,GACxB,OAAO,CAAC,MAAM,CAAC,CAmEjB"}
|