@technomoron/apicore-server 1.0.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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/api-module.cjs +34 -0
  3. package/dist/cjs/api-module.d.ts +45 -0
  4. package/dist/cjs/apicore-server.cjs +1561 -0
  5. package/dist/cjs/apicore-server.d.ts +288 -0
  6. package/dist/cjs/auth-api/auth-module.cjs +1248 -0
  7. package/dist/cjs/auth-api/auth-module.d.ts +116 -0
  8. package/dist/cjs/auth-api/compat-auth-storage.cjs +128 -0
  9. package/dist/cjs/auth-api/compat-auth-storage.d.ts +57 -0
  10. package/dist/cjs/auth-api/mem-auth-store.cjs +121 -0
  11. package/dist/cjs/auth-api/mem-auth-store.d.ts +68 -0
  12. package/dist/cjs/auth-api/module.cjs +25 -0
  13. package/dist/cjs/auth-api/module.d.ts +20 -0
  14. package/dist/cjs/auth-api/schemas.cjs +171 -0
  15. package/dist/cjs/auth-api/schemas.d.ts +21 -0
  16. package/dist/cjs/auth-api/sql-auth-store.cjs +179 -0
  17. package/dist/cjs/auth-api/sql-auth-store.d.ts +87 -0
  18. package/dist/cjs/auth-api/storage.cjs +102 -0
  19. package/dist/cjs/auth-api/storage.d.ts +38 -0
  20. package/dist/cjs/auth-api/types.cjs +2 -0
  21. package/dist/cjs/auth-api/types.d.ts +34 -0
  22. package/dist/cjs/auth-api/user-id.cjs +47 -0
  23. package/dist/cjs/auth-api/user-id.d.ts +5 -0
  24. package/dist/cjs/auth-cookie-options.cjs +66 -0
  25. package/dist/cjs/auth-cookie-options.d.ts +13 -0
  26. package/dist/cjs/base/client-info.cjs +285 -0
  27. package/dist/cjs/base/client-info.d.ts +27 -0
  28. package/dist/cjs/base/error-utils.cjs +50 -0
  29. package/dist/cjs/base/error-utils.d.ts +16 -0
  30. package/dist/cjs/base/request-utils.cjs +27 -0
  31. package/dist/cjs/base/request-utils.d.ts +8 -0
  32. package/dist/cjs/index.cjs +51 -0
  33. package/dist/cjs/index.d.ts +34 -0
  34. package/dist/cjs/limiter/auth-rate-limiter.cjs +35 -0
  35. package/dist/cjs/limiter/auth-rate-limiter.d.ts +12 -0
  36. package/dist/cjs/limiter/fixed-window.cjs +41 -0
  37. package/dist/cjs/limiter/fixed-window.d.ts +11 -0
  38. package/dist/cjs/oauth/base.cjs +7 -0
  39. package/dist/cjs/oauth/base.d.ts +17 -0
  40. package/dist/cjs/oauth/memory.cjs +135 -0
  41. package/dist/cjs/oauth/memory.d.ts +22 -0
  42. package/dist/cjs/oauth/models.cjs +47 -0
  43. package/dist/cjs/oauth/models.d.ts +50 -0
  44. package/dist/cjs/oauth/sequelize.cjs +159 -0
  45. package/dist/cjs/oauth/sequelize.d.ts +30 -0
  46. package/dist/cjs/oauth/types.cjs +3 -0
  47. package/dist/cjs/oauth/types.d.ts +51 -0
  48. package/dist/cjs/passkey/base.cjs +7 -0
  49. package/dist/cjs/passkey/base.d.ts +28 -0
  50. package/dist/cjs/passkey/config.cjs +26 -0
  51. package/dist/cjs/passkey/config.d.ts +2 -0
  52. package/dist/cjs/passkey/memory.cjs +123 -0
  53. package/dist/cjs/passkey/memory.d.ts +34 -0
  54. package/dist/cjs/passkey/models.cjs +142 -0
  55. package/dist/cjs/passkey/models.d.ts +34 -0
  56. package/dist/cjs/passkey/sequelize.cjs +126 -0
  57. package/dist/cjs/passkey/sequelize.d.ts +42 -0
  58. package/dist/cjs/passkey/service.cjs +413 -0
  59. package/dist/cjs/passkey/service.d.ts +21 -0
  60. package/dist/cjs/passkey/types.cjs +2 -0
  61. package/dist/cjs/passkey/types.d.ts +84 -0
  62. package/dist/cjs/sequelize-utils.cjs +56 -0
  63. package/dist/cjs/sequelize-utils.d.ts +8 -0
  64. package/dist/cjs/token/base.cjs +120 -0
  65. package/dist/cjs/token/base.d.ts +46 -0
  66. package/dist/cjs/token/memory.cjs +234 -0
  67. package/dist/cjs/token/memory.d.ts +29 -0
  68. package/dist/cjs/token/sequelize.cjs +400 -0
  69. package/dist/cjs/token/sequelize.d.ts +58 -0
  70. package/dist/cjs/token/types.cjs +2 -0
  71. package/dist/cjs/token/types.d.ts +34 -0
  72. package/dist/cjs/upload/memory.cjs +92 -0
  73. package/dist/cjs/upload/memory.d.ts +17 -0
  74. package/dist/cjs/upload/tus-module.cjs +270 -0
  75. package/dist/cjs/upload/tus-module.d.ts +38 -0
  76. package/dist/cjs/upload/types.cjs +2 -0
  77. package/dist/cjs/upload/types.d.ts +28 -0
  78. package/dist/cjs/user/base.cjs +53 -0
  79. package/dist/cjs/user/base.d.ts +36 -0
  80. package/dist/cjs/user/memory.cjs +194 -0
  81. package/dist/cjs/user/memory.d.ts +37 -0
  82. package/dist/cjs/user/sequelize.cjs +194 -0
  83. package/dist/cjs/user/sequelize.d.ts +46 -0
  84. package/dist/cjs/user/types.cjs +2 -0
  85. package/dist/cjs/user/types.d.ts +11 -0
  86. package/dist/esm/api-module.d.ts +45 -0
  87. package/dist/esm/api-module.js +30 -0
  88. package/dist/esm/apicore-server.d.ts +288 -0
  89. package/dist/esm/apicore-server.js +1552 -0
  90. package/dist/esm/auth-api/auth-module.d.ts +116 -0
  91. package/dist/esm/auth-api/auth-module.js +1246 -0
  92. package/dist/esm/auth-api/compat-auth-storage.d.ts +57 -0
  93. package/dist/esm/auth-api/compat-auth-storage.js +124 -0
  94. package/dist/esm/auth-api/mem-auth-store.d.ts +68 -0
  95. package/dist/esm/auth-api/mem-auth-store.js +117 -0
  96. package/dist/esm/auth-api/module.d.ts +20 -0
  97. package/dist/esm/auth-api/module.js +21 -0
  98. package/dist/esm/auth-api/schemas.d.ts +21 -0
  99. package/dist/esm/auth-api/schemas.js +168 -0
  100. package/dist/esm/auth-api/sql-auth-store.d.ts +87 -0
  101. package/dist/esm/auth-api/sql-auth-store.js +175 -0
  102. package/dist/esm/auth-api/storage.d.ts +38 -0
  103. package/dist/esm/auth-api/storage.js +98 -0
  104. package/dist/esm/auth-api/types.d.ts +34 -0
  105. package/dist/esm/auth-api/types.js +1 -0
  106. package/dist/esm/auth-api/user-id.d.ts +5 -0
  107. package/dist/esm/auth-api/user-id.js +41 -0
  108. package/dist/esm/auth-cookie-options.d.ts +13 -0
  109. package/dist/esm/auth-cookie-options.js +63 -0
  110. package/dist/esm/base/client-info.d.ts +27 -0
  111. package/dist/esm/base/client-info.js +282 -0
  112. package/dist/esm/base/error-utils.d.ts +16 -0
  113. package/dist/esm/base/error-utils.js +44 -0
  114. package/dist/esm/base/request-utils.d.ts +8 -0
  115. package/dist/esm/base/request-utils.js +23 -0
  116. package/dist/esm/index.d.ts +34 -0
  117. package/dist/esm/index.js +21 -0
  118. package/dist/esm/limiter/auth-rate-limiter.d.ts +12 -0
  119. package/dist/esm/limiter/auth-rate-limiter.js +32 -0
  120. package/dist/esm/limiter/fixed-window.d.ts +11 -0
  121. package/dist/esm/limiter/fixed-window.js +37 -0
  122. package/dist/esm/oauth/base.d.ts +17 -0
  123. package/dist/esm/oauth/base.js +3 -0
  124. package/dist/esm/oauth/memory.d.ts +22 -0
  125. package/dist/esm/oauth/memory.js +128 -0
  126. package/dist/esm/oauth/models.d.ts +50 -0
  127. package/dist/esm/oauth/models.js +38 -0
  128. package/dist/esm/oauth/sequelize.d.ts +30 -0
  129. package/dist/esm/oauth/sequelize.js +148 -0
  130. package/dist/esm/oauth/types.d.ts +51 -0
  131. package/dist/esm/oauth/types.js +2 -0
  132. package/dist/esm/passkey/base.d.ts +28 -0
  133. package/dist/esm/passkey/base.js +3 -0
  134. package/dist/esm/passkey/config.d.ts +2 -0
  135. package/dist/esm/passkey/config.js +23 -0
  136. package/dist/esm/passkey/memory.d.ts +34 -0
  137. package/dist/esm/passkey/memory.js +119 -0
  138. package/dist/esm/passkey/models.d.ts +34 -0
  139. package/dist/esm/passkey/models.js +135 -0
  140. package/dist/esm/passkey/sequelize.d.ts +42 -0
  141. package/dist/esm/passkey/sequelize.js +122 -0
  142. package/dist/esm/passkey/service.d.ts +21 -0
  143. package/dist/esm/passkey/service.js +376 -0
  144. package/dist/esm/passkey/types.d.ts +84 -0
  145. package/dist/esm/passkey/types.js +1 -0
  146. package/dist/esm/sequelize-utils.d.ts +8 -0
  147. package/dist/esm/sequelize-utils.js +47 -0
  148. package/dist/esm/token/base.d.ts +46 -0
  149. package/dist/esm/token/base.js +113 -0
  150. package/dist/esm/token/memory.d.ts +29 -0
  151. package/dist/esm/token/memory.js +230 -0
  152. package/dist/esm/token/sequelize.d.ts +58 -0
  153. package/dist/esm/token/sequelize.js +396 -0
  154. package/dist/esm/token/types.d.ts +34 -0
  155. package/dist/esm/token/types.js +1 -0
  156. package/dist/esm/upload/memory.d.ts +17 -0
  157. package/dist/esm/upload/memory.js +86 -0
  158. package/dist/esm/upload/tus-module.d.ts +38 -0
  159. package/dist/esm/upload/tus-module.js +266 -0
  160. package/dist/esm/upload/types.d.ts +28 -0
  161. package/dist/esm/upload/types.js +1 -0
  162. package/dist/esm/user/base.d.ts +36 -0
  163. package/dist/esm/user/base.js +46 -0
  164. package/dist/esm/user/memory.d.ts +37 -0
  165. package/dist/esm/user/memory.js +190 -0
  166. package/dist/esm/user/sequelize.d.ts +46 -0
  167. package/dist/esm/user/sequelize.js +188 -0
  168. package/dist/esm/user/types.d.ts +11 -0
  169. package/dist/esm/user/types.js +1 -0
  170. package/docs/swagger/openapi.json +2162 -0
  171. package/package.json +131 -0
@@ -0,0 +1,188 @@
1
+ import { DataTypes, Model, Op, UniqueConstraintError } from 'sequelize';
2
+ import { normalizeNumericUserId } from '../auth-api/user-id.js';
3
+ import { integerIdType, tableOptions } from '../sequelize-utils.js';
4
+ import { UserStore } from './base.js';
5
+ export class AuthUserModel extends Model {
6
+ }
7
+ export function initAuthUserModel(sequelize, options = {}) {
8
+ const idType = integerIdType(sequelize);
9
+ AuthUserModel.init({
10
+ user_id: {
11
+ type: idType,
12
+ autoIncrement: true,
13
+ allowNull: false,
14
+ primaryKey: true
15
+ },
16
+ login: {
17
+ type: DataTypes.STRING(64),
18
+ allowNull: false,
19
+ unique: true
20
+ },
21
+ email: {
22
+ type: DataTypes.STRING(100),
23
+ allowNull: false,
24
+ unique: true
25
+ },
26
+ password: {
27
+ type: DataTypes.STRING(255),
28
+ allowNull: false
29
+ }
30
+ }, {
31
+ ...tableOptions(sequelize, 'users', options.tablePrefix, { timestamps: false })
32
+ });
33
+ return AuthUserModel;
34
+ }
35
+ export class SequelizeUserStore extends UserStore {
36
+ constructor(options) {
37
+ super({
38
+ toPublic: options.toPublic,
39
+ bcryptRounds: options.bcryptRounds,
40
+ bcryptPepper: options.bcryptPepper
41
+ });
42
+ if (!options?.sequelize) {
43
+ throw new Error('SequelizeUserStore requires a configured Sequelize instance');
44
+ }
45
+ this.Users = options.userModel
46
+ ? options.userModel
47
+ : (options.userModelFactory ?? initAuthUserModel)(options.sequelize, {
48
+ tablePrefix: options.tablePrefix
49
+ });
50
+ this.recordMapper =
51
+ options.recordMapper ??
52
+ ((model) => SequelizeUserStore.mapModelToUser(model));
53
+ }
54
+ async findUser(identifier) {
55
+ const where = [];
56
+ try {
57
+ where.push({ user_id: this.normalizeUserId(identifier) });
58
+ }
59
+ catch {
60
+ // ignore
61
+ }
62
+ if (typeof identifier === 'string') {
63
+ where.push({ login: identifier });
64
+ where.push({ email: identifier });
65
+ }
66
+ if (where.length === 0) {
67
+ return null;
68
+ }
69
+ const model = await this.Users.findOne({ where: { [Op.or]: where } });
70
+ return model ? this.toUserRecord(model) : null;
71
+ }
72
+ async findById(id) {
73
+ try {
74
+ const model = await this.Users.findByPk(this.normalizeUserId(id));
75
+ return model ? this.toUserRecord(model) : null;
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ async findByLoginOrEmail(loginOrEmail) {
82
+ const model = await this.Users.findOne({
83
+ where: { [Op.or]: [{ login: loginOrEmail }, { email: loginOrEmail }] }
84
+ });
85
+ return model ? this.toUserRecord(model) : null;
86
+ }
87
+ async createUser(input) {
88
+ const normalized = this.normalizeUserInput(input);
89
+ const { password, ...rest } = normalized;
90
+ const defaults = {
91
+ ...rest,
92
+ password: password ? await this.hashPassword(password) : ''
93
+ };
94
+ const providedId = input.user_id;
95
+ if (providedId !== undefined && providedId !== null && Number.isFinite(providedId)) {
96
+ defaults.user_id = Number(providedId);
97
+ }
98
+ try {
99
+ const model = await this.Users.create(defaults);
100
+ return this.toUserRecord(model);
101
+ }
102
+ catch (error) {
103
+ if (error instanceof UniqueConstraintError) {
104
+ throw new Error(`User with login ${rest.login} or email ${rest.email} already exists`);
105
+ }
106
+ throw error;
107
+ }
108
+ }
109
+ async upsertUser(input) {
110
+ const normalized = this.normalizeUserInput(input);
111
+ const providedId = input.user_id;
112
+ if (providedId !== undefined) {
113
+ const model = await this.Users.findByPk(Number(providedId));
114
+ if (!model) {
115
+ throw new Error(`User ${String(providedId)} not found`);
116
+ }
117
+ const next = { ...normalized };
118
+ if (normalized.password && normalized.password.length > 0) {
119
+ next.password = await this.hashPassword(normalized.password);
120
+ }
121
+ else {
122
+ delete next.password;
123
+ }
124
+ await model.set(next);
125
+ try {
126
+ await model.save();
127
+ }
128
+ catch (error) {
129
+ if (error instanceof UniqueConstraintError) {
130
+ throw new Error(`User with login ${normalized.login} or email ${normalized.email} already exists`);
131
+ }
132
+ throw error;
133
+ }
134
+ return this.toUserRecord(model);
135
+ }
136
+ return this.createUser(input);
137
+ }
138
+ async updateUser(id, patch) {
139
+ const model = await this.Users.findByPk(this.normalizeUserId(id));
140
+ if (!model) {
141
+ throw new Error(`User ${String(id)} not found`);
142
+ }
143
+ const updates = { ...patch };
144
+ if (patch.password && patch.password.length > 0) {
145
+ updates.password = await this.hashPassword(patch.password);
146
+ }
147
+ else {
148
+ delete updates.password;
149
+ }
150
+ await model.set(updates);
151
+ try {
152
+ await model.save();
153
+ }
154
+ catch (error) {
155
+ if (error instanceof UniqueConstraintError) {
156
+ throw new Error(`User with login or email already exists`);
157
+ }
158
+ throw error;
159
+ }
160
+ return this.toUserRecord(model);
161
+ }
162
+ async setPasswordHash(id, hash) {
163
+ const [affected] = await this.Users.update({ password: hash }, { where: { user_id: this.normalizeUserId(id) } });
164
+ if (affected === 0) {
165
+ throw new Error(`User ${String(id)} not found`);
166
+ }
167
+ }
168
+ getPasswordHash(user) {
169
+ return user.password;
170
+ }
171
+ getUserId(user) {
172
+ return user.user_id;
173
+ }
174
+ toUserRecord(model) {
175
+ return this.recordMapper(model);
176
+ }
177
+ static mapModelToUser(model) {
178
+ return {
179
+ user_id: model.get('user_id'),
180
+ login: model.get('login'),
181
+ email: model.get('email'),
182
+ password: model.get('password')
183
+ };
184
+ }
185
+ normalizeUserId(identifier) {
186
+ return normalizeNumericUserId(identifier);
187
+ }
188
+ }
@@ -0,0 +1,11 @@
1
+ export interface BcryptHasherOptions {
2
+ rounds?: number;
3
+ pepper?: string;
4
+ }
5
+ export type CreateUserInput = Record<string, unknown> & {
6
+ login: string;
7
+ email: string;
8
+ password?: string;
9
+ };
10
+ export type UpdateUserInput = Partial<CreateUserInput>;
11
+ export type PublicUserMapper<User, PublicUser> = (user: User) => PublicUser;
@@ -0,0 +1 @@
1
+ export {};