najm-auth 2.0.15 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +261 -50
- package/dist/{NajmAuthClient-Cn9bObLB.d.ts → NajmAuthClient-DqGucYXi.d.ts} +3 -141
- package/dist/client/edge.d.ts +3 -18
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.js +15 -8
- package/dist/client/react/index.d.ts +11 -6
- package/dist/client/react/index.js +10 -3
- package/dist/client/server/index.d.ts +25 -78
- package/dist/client/server/index.js +104 -60
- package/dist/client/server/react.d.ts +48 -0
- package/dist/client/server/react.js +71 -0
- package/dist/client/server/reactClientGuard.d.ts +2 -0
- package/dist/client/server/reactClientGuard.js +4 -0
- package/dist/getSession-BthP85UA.d.ts +68 -0
- package/dist/identity/ma.d.ts +1 -0
- package/dist/identity/ma.js +64 -0
- package/dist/index.d.ts +395 -91
- package/dist/index.js +1733 -862
- package/dist/ma-sNHnUGLO.d.ts +88 -0
- package/dist/schema/pg.d.ts +260 -1
- package/dist/schema/pg.js +13 -0
- package/dist/schema/sqlite.d.ts +284 -1
- package/dist/schema/sqlite.js +14 -1
- package/dist/sessionRecovery-D5Fa0yZ1.d.ts +18 -0
- package/dist/types-BaSfgxqE.d.ts +166 -0
- package/package.json +15 -2
package/dist/schema/sqlite.d.ts
CHANGED
|
@@ -1089,6 +1089,149 @@ declare const credentialSetupSessionsTable: drizzle_orm_sqlite_core.SQLiteTableW
|
|
|
1089
1089
|
};
|
|
1090
1090
|
dialect: "sqlite";
|
|
1091
1091
|
}>;
|
|
1092
|
+
/**
|
|
1093
|
+
* Durable record that a user still owes a credential-setup purpose. Survives
|
|
1094
|
+
* browser sessions, unlike credential_setup_sessions — the composite key lets
|
|
1095
|
+
* one user owe more than one purpose at a time.
|
|
1096
|
+
*/
|
|
1097
|
+
declare const credentialSetupRequirementsTable: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
1098
|
+
name: "credential_setup_requirements";
|
|
1099
|
+
schema: undefined;
|
|
1100
|
+
columns: {
|
|
1101
|
+
userId: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1102
|
+
name: "user_id";
|
|
1103
|
+
tableName: "credential_setup_requirements";
|
|
1104
|
+
dataType: "string";
|
|
1105
|
+
columnType: "SQLiteText";
|
|
1106
|
+
data: string;
|
|
1107
|
+
driverParam: string;
|
|
1108
|
+
notNull: true;
|
|
1109
|
+
hasDefault: false;
|
|
1110
|
+
isPrimaryKey: false;
|
|
1111
|
+
isAutoincrement: false;
|
|
1112
|
+
hasRuntimeDefault: false;
|
|
1113
|
+
enumValues: [string, ...string[]];
|
|
1114
|
+
baseColumn: never;
|
|
1115
|
+
identity: undefined;
|
|
1116
|
+
generated: undefined;
|
|
1117
|
+
}, {}, {
|
|
1118
|
+
length: number;
|
|
1119
|
+
}>;
|
|
1120
|
+
purpose: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1121
|
+
name: "purpose";
|
|
1122
|
+
tableName: "credential_setup_requirements";
|
|
1123
|
+
dataType: "string";
|
|
1124
|
+
columnType: "SQLiteText";
|
|
1125
|
+
data: string;
|
|
1126
|
+
driverParam: string;
|
|
1127
|
+
notNull: true;
|
|
1128
|
+
hasDefault: false;
|
|
1129
|
+
isPrimaryKey: false;
|
|
1130
|
+
isAutoincrement: false;
|
|
1131
|
+
hasRuntimeDefault: false;
|
|
1132
|
+
enumValues: [string, ...string[]];
|
|
1133
|
+
baseColumn: never;
|
|
1134
|
+
identity: undefined;
|
|
1135
|
+
generated: undefined;
|
|
1136
|
+
}, {}, {
|
|
1137
|
+
length: number;
|
|
1138
|
+
}>;
|
|
1139
|
+
temporaryCredentialKind: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1140
|
+
name: "temporary_credential_kind";
|
|
1141
|
+
tableName: "credential_setup_requirements";
|
|
1142
|
+
dataType: "string";
|
|
1143
|
+
columnType: "SQLiteText";
|
|
1144
|
+
data: string;
|
|
1145
|
+
driverParam: string;
|
|
1146
|
+
notNull: false;
|
|
1147
|
+
hasDefault: false;
|
|
1148
|
+
isPrimaryKey: false;
|
|
1149
|
+
isAutoincrement: false;
|
|
1150
|
+
hasRuntimeDefault: false;
|
|
1151
|
+
enumValues: [string, ...string[]];
|
|
1152
|
+
baseColumn: never;
|
|
1153
|
+
identity: undefined;
|
|
1154
|
+
generated: undefined;
|
|
1155
|
+
}, {}, {
|
|
1156
|
+
length: number;
|
|
1157
|
+
}>;
|
|
1158
|
+
required: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1159
|
+
name: "required";
|
|
1160
|
+
tableName: "credential_setup_requirements";
|
|
1161
|
+
dataType: "boolean";
|
|
1162
|
+
columnType: "SQLiteBoolean";
|
|
1163
|
+
data: boolean;
|
|
1164
|
+
driverParam: number;
|
|
1165
|
+
notNull: true;
|
|
1166
|
+
hasDefault: true;
|
|
1167
|
+
isPrimaryKey: false;
|
|
1168
|
+
isAutoincrement: false;
|
|
1169
|
+
hasRuntimeDefault: false;
|
|
1170
|
+
enumValues: undefined;
|
|
1171
|
+
baseColumn: never;
|
|
1172
|
+
identity: undefined;
|
|
1173
|
+
generated: undefined;
|
|
1174
|
+
}, {}, {}>;
|
|
1175
|
+
completedAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1176
|
+
name: "completed_at";
|
|
1177
|
+
tableName: "credential_setup_requirements";
|
|
1178
|
+
dataType: "string";
|
|
1179
|
+
columnType: "SQLiteText";
|
|
1180
|
+
data: string;
|
|
1181
|
+
driverParam: string;
|
|
1182
|
+
notNull: false;
|
|
1183
|
+
hasDefault: false;
|
|
1184
|
+
isPrimaryKey: false;
|
|
1185
|
+
isAutoincrement: false;
|
|
1186
|
+
hasRuntimeDefault: false;
|
|
1187
|
+
enumValues: [string, ...string[]];
|
|
1188
|
+
baseColumn: never;
|
|
1189
|
+
identity: undefined;
|
|
1190
|
+
generated: undefined;
|
|
1191
|
+
}, {}, {
|
|
1192
|
+
length: number;
|
|
1193
|
+
}>;
|
|
1194
|
+
createdAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1195
|
+
name: "created_at";
|
|
1196
|
+
tableName: "credential_setup_requirements";
|
|
1197
|
+
dataType: "string";
|
|
1198
|
+
columnType: "SQLiteText";
|
|
1199
|
+
data: string;
|
|
1200
|
+
driverParam: string;
|
|
1201
|
+
notNull: false;
|
|
1202
|
+
hasDefault: true;
|
|
1203
|
+
isPrimaryKey: false;
|
|
1204
|
+
isAutoincrement: false;
|
|
1205
|
+
hasRuntimeDefault: true;
|
|
1206
|
+
enumValues: [string, ...string[]];
|
|
1207
|
+
baseColumn: never;
|
|
1208
|
+
identity: undefined;
|
|
1209
|
+
generated: undefined;
|
|
1210
|
+
}, {}, {
|
|
1211
|
+
length: number;
|
|
1212
|
+
}>;
|
|
1213
|
+
updatedAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
1214
|
+
name: "updated_at";
|
|
1215
|
+
tableName: "credential_setup_requirements";
|
|
1216
|
+
dataType: "string";
|
|
1217
|
+
columnType: "SQLiteText";
|
|
1218
|
+
data: string;
|
|
1219
|
+
driverParam: string;
|
|
1220
|
+
notNull: false;
|
|
1221
|
+
hasDefault: true;
|
|
1222
|
+
isPrimaryKey: false;
|
|
1223
|
+
isAutoincrement: false;
|
|
1224
|
+
hasRuntimeDefault: true;
|
|
1225
|
+
enumValues: [string, ...string[]];
|
|
1226
|
+
baseColumn: never;
|
|
1227
|
+
identity: undefined;
|
|
1228
|
+
generated: undefined;
|
|
1229
|
+
}, {}, {
|
|
1230
|
+
length: number;
|
|
1231
|
+
}>;
|
|
1232
|
+
};
|
|
1233
|
+
dialect: "sqlite";
|
|
1234
|
+
}>;
|
|
1092
1235
|
/**
|
|
1093
1236
|
* Junction table for many-to-many relationship between roles and permissions
|
|
1094
1237
|
*/
|
|
@@ -2018,6 +2161,144 @@ declare const authSchema: {
|
|
|
2018
2161
|
};
|
|
2019
2162
|
dialect: "sqlite";
|
|
2020
2163
|
}>;
|
|
2164
|
+
readonly credentialSetupRequirements: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
2165
|
+
name: "credential_setup_requirements";
|
|
2166
|
+
schema: undefined;
|
|
2167
|
+
columns: {
|
|
2168
|
+
userId: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2169
|
+
name: "user_id";
|
|
2170
|
+
tableName: "credential_setup_requirements";
|
|
2171
|
+
dataType: "string";
|
|
2172
|
+
columnType: "SQLiteText";
|
|
2173
|
+
data: string;
|
|
2174
|
+
driverParam: string;
|
|
2175
|
+
notNull: true;
|
|
2176
|
+
hasDefault: false;
|
|
2177
|
+
isPrimaryKey: false;
|
|
2178
|
+
isAutoincrement: false;
|
|
2179
|
+
hasRuntimeDefault: false;
|
|
2180
|
+
enumValues: [string, ...string[]];
|
|
2181
|
+
baseColumn: never;
|
|
2182
|
+
identity: undefined;
|
|
2183
|
+
generated: undefined;
|
|
2184
|
+
}, {}, {
|
|
2185
|
+
length: number;
|
|
2186
|
+
}>;
|
|
2187
|
+
purpose: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2188
|
+
name: "purpose";
|
|
2189
|
+
tableName: "credential_setup_requirements";
|
|
2190
|
+
dataType: "string";
|
|
2191
|
+
columnType: "SQLiteText";
|
|
2192
|
+
data: string;
|
|
2193
|
+
driverParam: string;
|
|
2194
|
+
notNull: true;
|
|
2195
|
+
hasDefault: false;
|
|
2196
|
+
isPrimaryKey: false;
|
|
2197
|
+
isAutoincrement: false;
|
|
2198
|
+
hasRuntimeDefault: false;
|
|
2199
|
+
enumValues: [string, ...string[]];
|
|
2200
|
+
baseColumn: never;
|
|
2201
|
+
identity: undefined;
|
|
2202
|
+
generated: undefined;
|
|
2203
|
+
}, {}, {
|
|
2204
|
+
length: number;
|
|
2205
|
+
}>;
|
|
2206
|
+
temporaryCredentialKind: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2207
|
+
name: "temporary_credential_kind";
|
|
2208
|
+
tableName: "credential_setup_requirements";
|
|
2209
|
+
dataType: "string";
|
|
2210
|
+
columnType: "SQLiteText";
|
|
2211
|
+
data: string;
|
|
2212
|
+
driverParam: string;
|
|
2213
|
+
notNull: false;
|
|
2214
|
+
hasDefault: false;
|
|
2215
|
+
isPrimaryKey: false;
|
|
2216
|
+
isAutoincrement: false;
|
|
2217
|
+
hasRuntimeDefault: false;
|
|
2218
|
+
enumValues: [string, ...string[]];
|
|
2219
|
+
baseColumn: never;
|
|
2220
|
+
identity: undefined;
|
|
2221
|
+
generated: undefined;
|
|
2222
|
+
}, {}, {
|
|
2223
|
+
length: number;
|
|
2224
|
+
}>;
|
|
2225
|
+
required: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2226
|
+
name: "required";
|
|
2227
|
+
tableName: "credential_setup_requirements";
|
|
2228
|
+
dataType: "boolean";
|
|
2229
|
+
columnType: "SQLiteBoolean";
|
|
2230
|
+
data: boolean;
|
|
2231
|
+
driverParam: number;
|
|
2232
|
+
notNull: true;
|
|
2233
|
+
hasDefault: true;
|
|
2234
|
+
isPrimaryKey: false;
|
|
2235
|
+
isAutoincrement: false;
|
|
2236
|
+
hasRuntimeDefault: false;
|
|
2237
|
+
enumValues: undefined;
|
|
2238
|
+
baseColumn: never;
|
|
2239
|
+
identity: undefined;
|
|
2240
|
+
generated: undefined;
|
|
2241
|
+
}, {}, {}>;
|
|
2242
|
+
completedAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2243
|
+
name: "completed_at";
|
|
2244
|
+
tableName: "credential_setup_requirements";
|
|
2245
|
+
dataType: "string";
|
|
2246
|
+
columnType: "SQLiteText";
|
|
2247
|
+
data: string;
|
|
2248
|
+
driverParam: string;
|
|
2249
|
+
notNull: false;
|
|
2250
|
+
hasDefault: false;
|
|
2251
|
+
isPrimaryKey: false;
|
|
2252
|
+
isAutoincrement: false;
|
|
2253
|
+
hasRuntimeDefault: false;
|
|
2254
|
+
enumValues: [string, ...string[]];
|
|
2255
|
+
baseColumn: never;
|
|
2256
|
+
identity: undefined;
|
|
2257
|
+
generated: undefined;
|
|
2258
|
+
}, {}, {
|
|
2259
|
+
length: number;
|
|
2260
|
+
}>;
|
|
2261
|
+
createdAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2262
|
+
name: "created_at";
|
|
2263
|
+
tableName: "credential_setup_requirements";
|
|
2264
|
+
dataType: "string";
|
|
2265
|
+
columnType: "SQLiteText";
|
|
2266
|
+
data: string;
|
|
2267
|
+
driverParam: string;
|
|
2268
|
+
notNull: false;
|
|
2269
|
+
hasDefault: true;
|
|
2270
|
+
isPrimaryKey: false;
|
|
2271
|
+
isAutoincrement: false;
|
|
2272
|
+
hasRuntimeDefault: true;
|
|
2273
|
+
enumValues: [string, ...string[]];
|
|
2274
|
+
baseColumn: never;
|
|
2275
|
+
identity: undefined;
|
|
2276
|
+
generated: undefined;
|
|
2277
|
+
}, {}, {
|
|
2278
|
+
length: number;
|
|
2279
|
+
}>;
|
|
2280
|
+
updatedAt: drizzle_orm_sqlite_core.SQLiteColumn<{
|
|
2281
|
+
name: "updated_at";
|
|
2282
|
+
tableName: "credential_setup_requirements";
|
|
2283
|
+
dataType: "string";
|
|
2284
|
+
columnType: "SQLiteText";
|
|
2285
|
+
data: string;
|
|
2286
|
+
driverParam: string;
|
|
2287
|
+
notNull: false;
|
|
2288
|
+
hasDefault: true;
|
|
2289
|
+
isPrimaryKey: false;
|
|
2290
|
+
isAutoincrement: false;
|
|
2291
|
+
hasRuntimeDefault: true;
|
|
2292
|
+
enumValues: [string, ...string[]];
|
|
2293
|
+
baseColumn: never;
|
|
2294
|
+
identity: undefined;
|
|
2295
|
+
generated: undefined;
|
|
2296
|
+
}, {}, {
|
|
2297
|
+
length: number;
|
|
2298
|
+
}>;
|
|
2299
|
+
};
|
|
2300
|
+
dialect: "sqlite";
|
|
2301
|
+
}>;
|
|
2021
2302
|
readonly roles: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
2022
2303
|
name: "roles";
|
|
2023
2304
|
schema: undefined;
|
|
@@ -2375,7 +2656,9 @@ type Token = typeof tokensTable.$inferSelect;
|
|
|
2375
2656
|
type NewToken = typeof tokensTable.$inferInsert;
|
|
2376
2657
|
type CredentialSetupSession = typeof credentialSetupSessionsTable.$inferSelect;
|
|
2377
2658
|
type NewCredentialSetupSession = typeof credentialSetupSessionsTable.$inferInsert;
|
|
2659
|
+
type CredentialSetupRequirement = typeof credentialSetupRequirementsTable.$inferSelect;
|
|
2660
|
+
type NewCredentialSetupRequirement = typeof credentialSetupRequirementsTable.$inferInsert;
|
|
2378
2661
|
type RolePermission = typeof rolePermissionsTable.$inferSelect;
|
|
2379
2662
|
type NewRolePermission = typeof rolePermissionsTable.$inferInsert;
|
|
2380
2663
|
|
|
2381
|
-
export { type CredentialSetupSession, type NewCredentialSetupSession, type NewOAuthAccount, type NewPermission, type NewRoleEntity, type NewRolePermission, type NewToken, type NewUser, type OAuthAccount, type Permission, type RoleEntity, type RolePermission, type Token, type User, authSchema, baseFields, credentialSetupSessionsTable, oauthAccountsTable, permissionsTable, rolePermissionsTable, rolesTable, tokensTable, usersTable };
|
|
2664
|
+
export { type CredentialSetupRequirement, type CredentialSetupSession, type NewCredentialSetupRequirement, type NewCredentialSetupSession, type NewOAuthAccount, type NewPermission, type NewRoleEntity, type NewRolePermission, type NewToken, type NewUser, type OAuthAccount, type Permission, type RoleEntity, type RolePermission, type Token, type User, authSchema, baseFields, credentialSetupRequirementsTable, credentialSetupSessionsTable, oauthAccountsTable, permissionsTable, rolePermissionsTable, rolesTable, tokensTable, usersTable };
|
package/dist/schema/sqlite.js
CHANGED
|
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/schema/sqlite.ts
|
|
5
|
-
import { sqliteTable, text, integer, uniqueIndex, index } from "drizzle-orm/sqlite-core";
|
|
5
|
+
import { sqliteTable, text, integer, primaryKey, uniqueIndex, index } from "drizzle-orm/sqlite-core";
|
|
6
6
|
import { sql } from "drizzle-orm";
|
|
7
7
|
import { nanoid } from "nanoid";
|
|
8
8
|
var baseFields = /* @__PURE__ */ __name((idLength = 5) => ({
|
|
@@ -76,6 +76,17 @@ var credentialSetupSessionsTable = sqliteTable("credential_setup_sessions", {
|
|
|
76
76
|
userPurposeIdx: index("credential_setup_sessions_user_purpose_idx").on(table.userId, table.purpose),
|
|
77
77
|
expiresAtIdx: index("credential_setup_sessions_expires_at_idx").on(table.expiresAt)
|
|
78
78
|
}));
|
|
79
|
+
var credentialSetupRequirementsTable = sqliteTable("credential_setup_requirements", {
|
|
80
|
+
userId: text("user_id").references(() => usersTable.id, { onDelete: "cascade" }).notNull(),
|
|
81
|
+
purpose: text("purpose").notNull(),
|
|
82
|
+
temporaryCredentialKind: text("temporary_credential_kind"),
|
|
83
|
+
required: integer("required", { mode: "boolean" }).default(true).notNull(),
|
|
84
|
+
completedAt: text("completed_at"),
|
|
85
|
+
createdAt: text("created_at").$defaultFn(() => (/* @__PURE__ */ new Date()).toISOString()),
|
|
86
|
+
updatedAt: text("updated_at").$defaultFn(() => (/* @__PURE__ */ new Date()).toISOString()).$onUpdate(() => sql`(datetime('now'))`)
|
|
87
|
+
}, (table) => ({
|
|
88
|
+
pk: primaryKey({ columns: [table.userId, table.purpose] })
|
|
89
|
+
}));
|
|
79
90
|
var rolePermissionsTable = sqliteTable("role_permissions", {
|
|
80
91
|
...baseFields(10),
|
|
81
92
|
roleId: text("role_id").notNull().references(() => rolesTable.id, { onDelete: "cascade" }),
|
|
@@ -88,6 +99,7 @@ var authSchema = {
|
|
|
88
99
|
oauthAccounts: oauthAccountsTable,
|
|
89
100
|
tokens: tokensTable,
|
|
90
101
|
credentialSetupSessions: credentialSetupSessionsTable,
|
|
102
|
+
credentialSetupRequirements: credentialSetupRequirementsTable,
|
|
91
103
|
roles: rolesTable,
|
|
92
104
|
permissions: permissionsTable,
|
|
93
105
|
rolePermissions: rolePermissionsTable
|
|
@@ -95,6 +107,7 @@ var authSchema = {
|
|
|
95
107
|
export {
|
|
96
108
|
authSchema,
|
|
97
109
|
baseFields,
|
|
110
|
+
credentialSetupRequirementsTable,
|
|
98
111
|
credentialSetupSessionsTable,
|
|
99
112
|
oauthAccountsTable,
|
|
100
113
|
permissionsTable,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type SessionRecoveryFailureReason = 'invalid-cookie-name' | 'invalid-refresh-cookie' | 'invalid-endpoint' | 'fetch-error' | 'http-status' | 'missing-set-cookie' | 'session-cookie-parse' | 'session-cookie-hmac' | 'session-cookie-payload';
|
|
2
|
+
interface SessionRecoveryErrorDetails {
|
|
3
|
+
name: string;
|
|
4
|
+
message: string;
|
|
5
|
+
code?: string;
|
|
6
|
+
cause?: {
|
|
7
|
+
name: string;
|
|
8
|
+
message: string;
|
|
9
|
+
code?: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
interface SessionRecoveryFailure {
|
|
13
|
+
reason: SessionRecoveryFailureReason;
|
|
14
|
+
httpStatus?: number;
|
|
15
|
+
error?: SessionRecoveryErrorDetails;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type { SessionRecoveryFailure as S, SessionRecoveryErrorDetails as a, SessionRecoveryFailureReason as b };
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User data from the auth server
|
|
3
|
+
*/
|
|
4
|
+
interface AuthUser {
|
|
5
|
+
id: string;
|
|
6
|
+
email: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
role?: string | null;
|
|
9
|
+
permissions?: string[];
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Full auth state snapshot
|
|
14
|
+
*/
|
|
15
|
+
interface AuthState {
|
|
16
|
+
user: AuthUser | null;
|
|
17
|
+
accessToken: string | null;
|
|
18
|
+
isAuthenticated: boolean;
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
roles: string[];
|
|
21
|
+
permissions: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Decoded JWT payload (client-side, no verification)
|
|
25
|
+
*/
|
|
26
|
+
interface DecodedToken {
|
|
27
|
+
userId: string;
|
|
28
|
+
jti?: string;
|
|
29
|
+
sessionVersion?: number;
|
|
30
|
+
roles?: string[];
|
|
31
|
+
permissions?: string[];
|
|
32
|
+
exp?: number;
|
|
33
|
+
iat?: number;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Server response envelope
|
|
38
|
+
*/
|
|
39
|
+
interface ServerResponse<T = unknown> {
|
|
40
|
+
data: T;
|
|
41
|
+
message?: string;
|
|
42
|
+
status?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Token pair from login/refresh (internal — refresh token is httpOnly cookie)
|
|
46
|
+
*/
|
|
47
|
+
interface TokenPair {
|
|
48
|
+
accessToken: string;
|
|
49
|
+
refreshToken?: string;
|
|
50
|
+
accessTokenExpiresAt?: number;
|
|
51
|
+
refreshTokenExpiresAt?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Login credentials. `identifier` accepts an email address or a phone number;
|
|
55
|
+
* `email` stays supported for existing callers.
|
|
56
|
+
*/
|
|
57
|
+
interface LoginCredentials {
|
|
58
|
+
identifier?: string;
|
|
59
|
+
email?: string;
|
|
60
|
+
password: string;
|
|
61
|
+
/** Persist the auth cookies past the browser closing. */
|
|
62
|
+
rememberMe?: boolean;
|
|
63
|
+
[key: string]: unknown;
|
|
64
|
+
}
|
|
65
|
+
/** The account must replace its credential before it gets a session. */
|
|
66
|
+
interface CredentialSetupPending {
|
|
67
|
+
nextStep: 'credential_setup';
|
|
68
|
+
setupRequired: true;
|
|
69
|
+
purpose: string;
|
|
70
|
+
expiresAt: string;
|
|
71
|
+
}
|
|
72
|
+
interface AuthenticatedLogin {
|
|
73
|
+
nextStep: 'authenticated';
|
|
74
|
+
user: AuthUser;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Login answer. Branch on `nextStep`: `credential_setup` carries no tokens and
|
|
78
|
+
* leaves the client unauthenticated.
|
|
79
|
+
*/
|
|
80
|
+
type LoginResult = AuthenticatedLogin | CredentialSetupPending;
|
|
81
|
+
/**
|
|
82
|
+
* Retry configuration
|
|
83
|
+
*/
|
|
84
|
+
interface RetryConfig {
|
|
85
|
+
maxRetries?: number;
|
|
86
|
+
backoff?: 'exponential' | 'linear';
|
|
87
|
+
baseDelay?: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Auth client configuration
|
|
91
|
+
*/
|
|
92
|
+
interface AuthClientConfig {
|
|
93
|
+
/** API base URL (e.g., '/api' or 'https://api.example.com') */
|
|
94
|
+
baseURL: string;
|
|
95
|
+
/** Auth endpoints prefix (default: '/auth') */
|
|
96
|
+
authPrefix?: string;
|
|
97
|
+
/** Proactive refresh at this fraction of token lifetime (default: 0.8) */
|
|
98
|
+
refreshThreshold?: number;
|
|
99
|
+
/** Enable multi-tab sync via BroadcastChannel (default: true) */
|
|
100
|
+
tabSync?: boolean;
|
|
101
|
+
/** BroadcastChannel name (default: 'najm-auth') */
|
|
102
|
+
channelName?: string;
|
|
103
|
+
/** Network retry configuration */
|
|
104
|
+
retry?: RetryConfig;
|
|
105
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
106
|
+
timeout?: number;
|
|
107
|
+
}
|
|
108
|
+
type OAuthProvider = 'google';
|
|
109
|
+
interface OAuthLoginOptions {
|
|
110
|
+
/** Same-origin frontend path after OAuth completes. */
|
|
111
|
+
returnTo?: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Auth event types
|
|
115
|
+
*/
|
|
116
|
+
interface AuthEventMap {
|
|
117
|
+
login: AuthUser;
|
|
118
|
+
logout: null;
|
|
119
|
+
/** Emitted when server-side logout invalidation fails (state was already cleared) */
|
|
120
|
+
logoutError: unknown;
|
|
121
|
+
tokenRefresh: null;
|
|
122
|
+
sessionExpired: null;
|
|
123
|
+
stateChange: AuthState;
|
|
124
|
+
userUpdated: AuthUser;
|
|
125
|
+
}
|
|
126
|
+
type AuthEvent = keyof AuthEventMap;
|
|
127
|
+
type AuthEventHandler<K extends AuthEvent = AuthEvent> = (data: AuthEventMap[K]) => void;
|
|
128
|
+
/**
|
|
129
|
+
* Tab sync message types
|
|
130
|
+
*/
|
|
131
|
+
type TabSyncMessage = {
|
|
132
|
+
type: 'logout';
|
|
133
|
+
} | {
|
|
134
|
+
type: 'sync';
|
|
135
|
+
state: SyncPayload;
|
|
136
|
+
};
|
|
137
|
+
interface SyncPayload {
|
|
138
|
+
accessToken: string | null;
|
|
139
|
+
user: AuthUser | null;
|
|
140
|
+
roles: string[];
|
|
141
|
+
permissions: string[];
|
|
142
|
+
isAuthenticated: boolean;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* FetchClient request options
|
|
146
|
+
*/
|
|
147
|
+
interface RequestOptions {
|
|
148
|
+
body?: unknown;
|
|
149
|
+
headers?: Record<string, string>;
|
|
150
|
+
signal?: AbortSignal;
|
|
151
|
+
timeout?: number;
|
|
152
|
+
/** Skip auth header attachment (for public endpoints like /login, /register) */
|
|
153
|
+
skipAuth?: boolean;
|
|
154
|
+
/** @internal Prevents 401-refresh loop after a single retry */
|
|
155
|
+
_retried?: boolean;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Auth error thrown by the client
|
|
159
|
+
*/
|
|
160
|
+
declare class AuthError extends Error {
|
|
161
|
+
status: number;
|
|
162
|
+
body?: unknown;
|
|
163
|
+
constructor(status: number, message: string, body?: unknown);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export { type AuthUser as A, type CredentialSetupPending as C, type DecodedToken as D, type LoginCredentials as L, type OAuthProvider as O, type RetryConfig as R, type SyncPayload as S, type TabSyncMessage as T, type RequestOptions as a, type AuthClientConfig as b, type LoginResult as c, type OAuthLoginOptions as d, type AuthState as e, type AuthEvent as f, type AuthEventHandler as g, AuthError as h, type AuthEventMap as i, type AuthenticatedLogin as j, type ServerResponse as k, type TokenPair as l };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "najm-auth",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Authentication and authorization library for najm framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -34,6 +34,18 @@
|
|
|
34
34
|
"import": "./dist/client/server/index.js",
|
|
35
35
|
"default": "./dist/client/server/index.js"
|
|
36
36
|
},
|
|
37
|
+
"./client/server/react": {
|
|
38
|
+
"types": "./dist/client/server/react.d.ts",
|
|
39
|
+
"react-server": "./dist/client/server/react.js",
|
|
40
|
+
"browser": "./dist/client/server/reactClientGuard.js",
|
|
41
|
+
"import": "./dist/client/server/react.js",
|
|
42
|
+
"default": "./dist/client/server/react.js"
|
|
43
|
+
},
|
|
44
|
+
"./identity/ma": {
|
|
45
|
+
"types": "./dist/identity/ma.d.ts",
|
|
46
|
+
"import": "./dist/identity/ma.js",
|
|
47
|
+
"default": "./dist/identity/ma.js"
|
|
48
|
+
},
|
|
37
49
|
"./pg": {
|
|
38
50
|
"types": "./dist/schema/pg.d.ts",
|
|
39
51
|
"import": "./dist/schema/pg.js",
|
|
@@ -47,7 +59,8 @@
|
|
|
47
59
|
},
|
|
48
60
|
"scripts": {
|
|
49
61
|
"build": "tsup",
|
|
50
|
-
"test": "bun test",
|
|
62
|
+
"test": "bun test && bun run test:rsc",
|
|
63
|
+
"test:rsc": "bun test --conditions react-server test/react-server-auth.test.ts",
|
|
51
64
|
"test:next16": "bun run build && bun integration/next16-proxy/run.ts",
|
|
52
65
|
"test:watch": "bun test --watch",
|
|
53
66
|
"start": "bun --watch src/main.ts",
|