@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.
- package/LICENSE +21 -0
- package/dist/cjs/api-module.cjs +34 -0
- package/dist/cjs/api-module.d.ts +45 -0
- package/dist/cjs/apicore-server.cjs +1561 -0
- package/dist/cjs/apicore-server.d.ts +288 -0
- package/dist/cjs/auth-api/auth-module.cjs +1248 -0
- package/dist/cjs/auth-api/auth-module.d.ts +116 -0
- package/dist/cjs/auth-api/compat-auth-storage.cjs +128 -0
- package/dist/cjs/auth-api/compat-auth-storage.d.ts +57 -0
- package/dist/cjs/auth-api/mem-auth-store.cjs +121 -0
- package/dist/cjs/auth-api/mem-auth-store.d.ts +68 -0
- package/dist/cjs/auth-api/module.cjs +25 -0
- package/dist/cjs/auth-api/module.d.ts +20 -0
- package/dist/cjs/auth-api/schemas.cjs +171 -0
- package/dist/cjs/auth-api/schemas.d.ts +21 -0
- package/dist/cjs/auth-api/sql-auth-store.cjs +179 -0
- package/dist/cjs/auth-api/sql-auth-store.d.ts +87 -0
- package/dist/cjs/auth-api/storage.cjs +102 -0
- package/dist/cjs/auth-api/storage.d.ts +38 -0
- package/dist/cjs/auth-api/types.cjs +2 -0
- package/dist/cjs/auth-api/types.d.ts +34 -0
- package/dist/cjs/auth-api/user-id.cjs +47 -0
- package/dist/cjs/auth-api/user-id.d.ts +5 -0
- package/dist/cjs/auth-cookie-options.cjs +66 -0
- package/dist/cjs/auth-cookie-options.d.ts +13 -0
- package/dist/cjs/base/client-info.cjs +285 -0
- package/dist/cjs/base/client-info.d.ts +27 -0
- package/dist/cjs/base/error-utils.cjs +50 -0
- package/dist/cjs/base/error-utils.d.ts +16 -0
- package/dist/cjs/base/request-utils.cjs +27 -0
- package/dist/cjs/base/request-utils.d.ts +8 -0
- package/dist/cjs/index.cjs +51 -0
- package/dist/cjs/index.d.ts +34 -0
- package/dist/cjs/limiter/auth-rate-limiter.cjs +35 -0
- package/dist/cjs/limiter/auth-rate-limiter.d.ts +12 -0
- package/dist/cjs/limiter/fixed-window.cjs +41 -0
- package/dist/cjs/limiter/fixed-window.d.ts +11 -0
- package/dist/cjs/oauth/base.cjs +7 -0
- package/dist/cjs/oauth/base.d.ts +17 -0
- package/dist/cjs/oauth/memory.cjs +135 -0
- package/dist/cjs/oauth/memory.d.ts +22 -0
- package/dist/cjs/oauth/models.cjs +47 -0
- package/dist/cjs/oauth/models.d.ts +50 -0
- package/dist/cjs/oauth/sequelize.cjs +159 -0
- package/dist/cjs/oauth/sequelize.d.ts +30 -0
- package/dist/cjs/oauth/types.cjs +3 -0
- package/dist/cjs/oauth/types.d.ts +51 -0
- package/dist/cjs/passkey/base.cjs +7 -0
- package/dist/cjs/passkey/base.d.ts +28 -0
- package/dist/cjs/passkey/config.cjs +26 -0
- package/dist/cjs/passkey/config.d.ts +2 -0
- package/dist/cjs/passkey/memory.cjs +123 -0
- package/dist/cjs/passkey/memory.d.ts +34 -0
- package/dist/cjs/passkey/models.cjs +142 -0
- package/dist/cjs/passkey/models.d.ts +34 -0
- package/dist/cjs/passkey/sequelize.cjs +126 -0
- package/dist/cjs/passkey/sequelize.d.ts +42 -0
- package/dist/cjs/passkey/service.cjs +413 -0
- package/dist/cjs/passkey/service.d.ts +21 -0
- package/dist/cjs/passkey/types.cjs +2 -0
- package/dist/cjs/passkey/types.d.ts +84 -0
- package/dist/cjs/sequelize-utils.cjs +56 -0
- package/dist/cjs/sequelize-utils.d.ts +8 -0
- package/dist/cjs/token/base.cjs +120 -0
- package/dist/cjs/token/base.d.ts +46 -0
- package/dist/cjs/token/memory.cjs +234 -0
- package/dist/cjs/token/memory.d.ts +29 -0
- package/dist/cjs/token/sequelize.cjs +400 -0
- package/dist/cjs/token/sequelize.d.ts +58 -0
- package/dist/cjs/token/types.cjs +2 -0
- package/dist/cjs/token/types.d.ts +34 -0
- package/dist/cjs/upload/memory.cjs +92 -0
- package/dist/cjs/upload/memory.d.ts +17 -0
- package/dist/cjs/upload/tus-module.cjs +270 -0
- package/dist/cjs/upload/tus-module.d.ts +38 -0
- package/dist/cjs/upload/types.cjs +2 -0
- package/dist/cjs/upload/types.d.ts +28 -0
- package/dist/cjs/user/base.cjs +53 -0
- package/dist/cjs/user/base.d.ts +36 -0
- package/dist/cjs/user/memory.cjs +194 -0
- package/dist/cjs/user/memory.d.ts +37 -0
- package/dist/cjs/user/sequelize.cjs +194 -0
- package/dist/cjs/user/sequelize.d.ts +46 -0
- package/dist/cjs/user/types.cjs +2 -0
- package/dist/cjs/user/types.d.ts +11 -0
- package/dist/esm/api-module.d.ts +45 -0
- package/dist/esm/api-module.js +30 -0
- package/dist/esm/apicore-server.d.ts +288 -0
- package/dist/esm/apicore-server.js +1552 -0
- package/dist/esm/auth-api/auth-module.d.ts +116 -0
- package/dist/esm/auth-api/auth-module.js +1246 -0
- package/dist/esm/auth-api/compat-auth-storage.d.ts +57 -0
- package/dist/esm/auth-api/compat-auth-storage.js +124 -0
- package/dist/esm/auth-api/mem-auth-store.d.ts +68 -0
- package/dist/esm/auth-api/mem-auth-store.js +117 -0
- package/dist/esm/auth-api/module.d.ts +20 -0
- package/dist/esm/auth-api/module.js +21 -0
- package/dist/esm/auth-api/schemas.d.ts +21 -0
- package/dist/esm/auth-api/schemas.js +168 -0
- package/dist/esm/auth-api/sql-auth-store.d.ts +87 -0
- package/dist/esm/auth-api/sql-auth-store.js +175 -0
- package/dist/esm/auth-api/storage.d.ts +38 -0
- package/dist/esm/auth-api/storage.js +98 -0
- package/dist/esm/auth-api/types.d.ts +34 -0
- package/dist/esm/auth-api/types.js +1 -0
- package/dist/esm/auth-api/user-id.d.ts +5 -0
- package/dist/esm/auth-api/user-id.js +41 -0
- package/dist/esm/auth-cookie-options.d.ts +13 -0
- package/dist/esm/auth-cookie-options.js +63 -0
- package/dist/esm/base/client-info.d.ts +27 -0
- package/dist/esm/base/client-info.js +282 -0
- package/dist/esm/base/error-utils.d.ts +16 -0
- package/dist/esm/base/error-utils.js +44 -0
- package/dist/esm/base/request-utils.d.ts +8 -0
- package/dist/esm/base/request-utils.js +23 -0
- package/dist/esm/index.d.ts +34 -0
- package/dist/esm/index.js +21 -0
- package/dist/esm/limiter/auth-rate-limiter.d.ts +12 -0
- package/dist/esm/limiter/auth-rate-limiter.js +32 -0
- package/dist/esm/limiter/fixed-window.d.ts +11 -0
- package/dist/esm/limiter/fixed-window.js +37 -0
- package/dist/esm/oauth/base.d.ts +17 -0
- package/dist/esm/oauth/base.js +3 -0
- package/dist/esm/oauth/memory.d.ts +22 -0
- package/dist/esm/oauth/memory.js +128 -0
- package/dist/esm/oauth/models.d.ts +50 -0
- package/dist/esm/oauth/models.js +38 -0
- package/dist/esm/oauth/sequelize.d.ts +30 -0
- package/dist/esm/oauth/sequelize.js +148 -0
- package/dist/esm/oauth/types.d.ts +51 -0
- package/dist/esm/oauth/types.js +2 -0
- package/dist/esm/passkey/base.d.ts +28 -0
- package/dist/esm/passkey/base.js +3 -0
- package/dist/esm/passkey/config.d.ts +2 -0
- package/dist/esm/passkey/config.js +23 -0
- package/dist/esm/passkey/memory.d.ts +34 -0
- package/dist/esm/passkey/memory.js +119 -0
- package/dist/esm/passkey/models.d.ts +34 -0
- package/dist/esm/passkey/models.js +135 -0
- package/dist/esm/passkey/sequelize.d.ts +42 -0
- package/dist/esm/passkey/sequelize.js +122 -0
- package/dist/esm/passkey/service.d.ts +21 -0
- package/dist/esm/passkey/service.js +376 -0
- package/dist/esm/passkey/types.d.ts +84 -0
- package/dist/esm/passkey/types.js +1 -0
- package/dist/esm/sequelize-utils.d.ts +8 -0
- package/dist/esm/sequelize-utils.js +47 -0
- package/dist/esm/token/base.d.ts +46 -0
- package/dist/esm/token/base.js +113 -0
- package/dist/esm/token/memory.d.ts +29 -0
- package/dist/esm/token/memory.js +230 -0
- package/dist/esm/token/sequelize.d.ts +58 -0
- package/dist/esm/token/sequelize.js +396 -0
- package/dist/esm/token/types.d.ts +34 -0
- package/dist/esm/token/types.js +1 -0
- package/dist/esm/upload/memory.d.ts +17 -0
- package/dist/esm/upload/memory.js +86 -0
- package/dist/esm/upload/tus-module.d.ts +38 -0
- package/dist/esm/upload/tus-module.js +266 -0
- package/dist/esm/upload/types.d.ts +28 -0
- package/dist/esm/upload/types.js +1 -0
- package/dist/esm/user/base.d.ts +36 -0
- package/dist/esm/user/base.js +46 -0
- package/dist/esm/user/memory.d.ts +37 -0
- package/dist/esm/user/memory.js +190 -0
- package/dist/esm/user/sequelize.d.ts +46 -0
- package/dist/esm/user/sequelize.js +188 -0
- package/dist/esm/user/types.d.ts +11 -0
- package/dist/esm/user/types.js +1 -0
- package/docs/swagger/openapi.json +2162 -0
- 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 {};
|