@foir/sdk 0.21.0 → 0.23.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/CHANGELOG.md +135 -1
- package/README.md +15 -15
- package/dist/app/client.d.ts +93 -86
- package/dist/app/contract/proto/apps/v1/apps_pb.d.ts +14 -13
- package/dist/app/dispatch.d.ts +5 -5
- package/dist/app/errors.d.ts +17 -15
- package/dist/app/index.d.ts +4 -4
- package/dist/app/naming.d.ts +1 -1
- package/dist/app/ticket.d.ts +2 -2
- package/dist/app/vocabulary.generated.d.ts +2 -2
- package/dist/app-contract.js +3 -3
- package/dist/app.js +92 -90
- package/dist/auth/access.d.ts +19 -19
- package/dist/auth/auth.d.ts +251 -117
- package/dist/auth/grant-table.generated.d.ts +5 -4
- package/dist/auth/hosted.d.ts +38 -14
- package/dist/auth/index.d.ts +9 -9
- package/dist/auth/operations.d.ts +153 -33
- package/dist/auth/ops.d.ts +39 -21
- package/dist/auth/session-client.d.ts +3 -3
- package/dist/auth-session.js +3 -3
- package/dist/auth.js +400 -250
- package/dist/client.js +5 -8
- package/dist/codegen/preset.d.ts +1 -1
- package/dist/data/builtins.d.ts +26 -26
- package/dist/data/client.d.ts +3 -3
- package/dist/data/decimal.d.ts +1 -1
- package/dist/data/index.d.ts +1 -1
- package/dist/data/manifest.d.ts +1 -1
- package/dist/data/schema.d.ts +2 -2
- package/dist/data/transport.d.ts +14 -13
- package/dist/data/ws-transport.d.ts +1 -1
- package/dist/data.js +8 -11
- package/dist/graphql/content-client.d.ts +13 -13
- package/dist/index.js +1 -4
- package/dist/live/drift.d.ts +1 -1
- package/dist/media/screen-capture.d.ts +1 -1
- package/dist/next/index.d.ts +2 -2
- package/dist/next/session.d.ts +10 -10
- package/dist/next.js +78 -60
- package/dist/placement/index.d.ts +13 -13
- package/dist/placement.js +127 -116
- package/dist/push.js +62 -44
- package/dist/react/FoirFeedback.d.ts +2 -2
- package/dist/react/FoirProvider.d.ts +24 -24
- package/dist/react/SignIn.d.ts +4 -4
- package/dist/react/UserButton.d.ts +1 -1
- package/dist/react/feedback-notes.d.ts +8 -6
- package/dist/react/index.d.ts +3 -3
- package/dist/react.js +238 -209
- package/dist/realtime/index.d.ts +1 -1
- package/dist/server/callback-client.d.ts +4 -4
- package/dist/server/events-client.d.ts +21 -21
- package/dist/server/operation-types.d.ts +8 -8
- package/dist/server/require-scoped-token.d.ts +3 -3
- package/dist/server/types.d.ts +2 -2
- package/dist/server/verify-scoped-token.d.ts +3 -3
- package/dist/server.js +130 -126
- package/dist/transport/foir-http.d.ts +14 -14
- package/dist/transport/key-kind.d.ts +1 -12
- package/dist/types/index.d.ts +2 -2
- package/package.json +1 -1
package/dist/auth.js
CHANGED
|
@@ -5,10 +5,7 @@ import { print as print2 } from "graphql";
|
|
|
5
5
|
var KEY_PREFIXES = [
|
|
6
6
|
["foir_pub_", "publishable"],
|
|
7
7
|
["foir_srv_", "server"],
|
|
8
|
-
["foir_adm_", "admin"]
|
|
9
|
-
["pk_", "publishable"],
|
|
10
|
-
["sk_", "older"],
|
|
11
|
-
["tc_", "older"]
|
|
8
|
+
["foir_adm_", "admin"]
|
|
12
9
|
];
|
|
13
10
|
var FOIR_CREDENTIALS_DOC = "https://docs.foir.dev/credentials";
|
|
14
11
|
function foirKeyKind(apiKey) {
|
|
@@ -217,8 +214,8 @@ var FoirAuthDowngradedError = class extends FoirRequestError {
|
|
|
217
214
|
downgrade;
|
|
218
215
|
constructor(downgrade) {
|
|
219
216
|
super(
|
|
220
|
-
`[foir] your
|
|
221
|
-
{ graphQLErrors: [{ message: "
|
|
217
|
+
`[foir] your user token was ${downgrade.userToken} (${downgrade.reason}), so the request was served as ${downgrade.servedAs}`,
|
|
218
|
+
{ graphQLErrors: [{ message: "user token rejected", extensions: { code: "AUTH_DOWNGRADED" } }] }
|
|
222
219
|
);
|
|
223
220
|
this.name = "FoirAuthDowngradedError";
|
|
224
221
|
this.downgrade = downgrade;
|
|
@@ -226,7 +223,7 @@ var FoirAuthDowngradedError = class extends FoirRequestError {
|
|
|
226
223
|
};
|
|
227
224
|
var FoirSessionExpiredError = class extends FoirRequestError {
|
|
228
225
|
constructor(options) {
|
|
229
|
-
super("[foir] the
|
|
226
|
+
super("[foir] the user session has expired and could not be refreshed: sign in again", {
|
|
230
227
|
cause: options?.cause,
|
|
231
228
|
graphQLErrors: [{ message: "session expired", extensions: { code: "SESSION_EXPIRED" } }]
|
|
232
229
|
});
|
|
@@ -243,7 +240,7 @@ function reportAuthDowngrade(envelope) {
|
|
|
243
240
|
if (warnedDowngrade === downgrade.reason) return;
|
|
244
241
|
warnedDowngrade = downgrade.reason;
|
|
245
242
|
console.warn(
|
|
246
|
-
`[foir] your
|
|
243
|
+
`[foir] your user token was ${downgrade.userToken} (${downgrade.reason}) \u2014 this request was served as ${downgrade.servedAs}, so auth-targeted content resolved to its anonymous variant. ` + (downgrade.reason === "expired" ? "Re-exchange the token and retry." : "Check which credential you are sending.")
|
|
247
244
|
);
|
|
248
245
|
}
|
|
249
246
|
function refusePrunedDocument(json, options) {
|
|
@@ -1076,42 +1073,63 @@ var AUTH_OPS = {
|
|
|
1076
1073
|
authConfig: "authConfig",
|
|
1077
1074
|
authProviders: "authProviders",
|
|
1078
1075
|
defaultAuthProvider: "defaultAuthProvider",
|
|
1079
|
-
|
|
1076
|
+
signupContext: "signupContext",
|
|
1080
1077
|
// Post-credential self reads.
|
|
1081
1078
|
currentUser: "currentUser",
|
|
1082
1079
|
myProviderToken: "myProviderToken",
|
|
1083
|
-
// What the calling credential may do, and for a signed-in
|
|
1080
|
+
// What the calling credential may do, and for a signed-in user the roles
|
|
1084
1081
|
// they hold. `./access` reads it.
|
|
1085
1082
|
whoami: "whoami",
|
|
1086
1083
|
// Methods.
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1084
|
+
login: "login",
|
|
1085
|
+
register: "register",
|
|
1086
|
+
requestOTP: "requestOTP",
|
|
1087
|
+
loginWithOTP: "loginWithOTP",
|
|
1091
1088
|
// Session lifecycle.
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
// Password management and account lifecycle
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1089
|
+
refreshToken: "refreshToken",
|
|
1090
|
+
logout: "logout",
|
|
1091
|
+
joinWaitlist: "joinWaitlist",
|
|
1092
|
+
// Password management and account lifecycle.
|
|
1093
|
+
requestPasswordReset: "requestPasswordReset",
|
|
1094
|
+
resetPassword: "resetPassword",
|
|
1095
|
+
updatePassword: "updatePassword",
|
|
1096
|
+
verifyEmail: "verifyEmail",
|
|
1100
1097
|
deleteMyAccount: "deleteMyAccount",
|
|
1101
|
-
// The
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
//
|
|
1106
|
-
//
|
|
1098
|
+
// The user's own profile, and the apps they have agreed may act for them.
|
|
1099
|
+
updateMyProfile: "updateMyProfile",
|
|
1100
|
+
myAuthorizedApps: "myAuthorizedApps",
|
|
1101
|
+
revokeAuthorizedApp: "revokeAuthorizedApp",
|
|
1102
|
+
// Where they are signed in, their personal access tokens, and the
|
|
1103
|
+
// providers they sign in with.
|
|
1104
|
+
mySessions: "mySessions",
|
|
1105
|
+
endMySession: "endMySession",
|
|
1106
|
+
signOutEverywhere: "signOutEverywhere",
|
|
1107
|
+
createPersonalAccessToken: "createPersonalAccessToken",
|
|
1108
|
+
mySignInMethods: "mySignInMethods",
|
|
1109
|
+
connectSignInMethod: "connectSignInMethod",
|
|
1110
|
+
disconnectSignInMethod: "disconnectSignInMethod",
|
|
1111
|
+
// Their second factors. A change needs one proven first, by a step-up.
|
|
1112
|
+
myFactors: "myFactors",
|
|
1113
|
+
beginStepUp: "beginStepUp",
|
|
1114
|
+
completeStepUp: "completeStepUp",
|
|
1115
|
+
beginFactorEnrollment: "beginFactorEnrollment",
|
|
1116
|
+
completeFactorEnrollment: "completeFactorEnrollment",
|
|
1117
|
+
removeFactor: "removeFactor",
|
|
1118
|
+
makeRecoveryCodes: "makeRecoveryCodes",
|
|
1119
|
+
// The organizations the caller may stand in. Nothing selects one: a request
|
|
1120
|
+
// names the organization it acts in (`orgId` or `orgUrl` below), and the
|
|
1121
|
+
// platform checks the caller stands there every time.
|
|
1107
1122
|
myOrganizations: "myOrganizations",
|
|
1108
|
-
selectMyOrganization: "selectMyOrganization",
|
|
1109
1123
|
// Founding one. Present in a manifest only when the project opted in.
|
|
1110
|
-
|
|
1124
|
+
registerOrganization: "registerOrganization",
|
|
1111
1125
|
// External identity providers.
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1126
|
+
loginWithProvider: "loginWithProvider",
|
|
1127
|
+
providerCallback: "providerCallback",
|
|
1128
|
+
providerVerifyOTP: "providerVerifyOTP",
|
|
1129
|
+
// A provider sign-in that names an address somebody already holds, waiting
|
|
1130
|
+
// for the code sent to it.
|
|
1131
|
+
confirmProviderLink: "confirmProviderLink",
|
|
1132
|
+
resendProviderLinkCode: "resendProviderLinkCode"
|
|
1115
1133
|
};
|
|
1116
1134
|
function authClientConfig(env, options) {
|
|
1117
1135
|
const apiKey = resolveFoirApiKey(env);
|
|
@@ -1174,31 +1192,58 @@ function stripUndefined(args) {
|
|
|
1174
1192
|
// src/auth/auth.ts
|
|
1175
1193
|
var TOKEN_KEY = "foir:token";
|
|
1176
1194
|
var REFRESH_KEY = "foir:refreshToken";
|
|
1177
|
-
var
|
|
1195
|
+
var USER_ID_KEY = "foir:userId";
|
|
1178
1196
|
var EMAIL_KEY = "foir:email";
|
|
1179
|
-
async function
|
|
1180
|
-
return authOp(env, AUTH_OPS.
|
|
1197
|
+
async function login(env, vars) {
|
|
1198
|
+
return authOp(env, AUTH_OPS.login, vars);
|
|
1181
1199
|
}
|
|
1182
|
-
async function
|
|
1183
|
-
return authOp(env, AUTH_OPS.
|
|
1200
|
+
async function register(env, vars) {
|
|
1201
|
+
return authOp(env, AUTH_OPS.register, vars);
|
|
1184
1202
|
}
|
|
1185
|
-
async function
|
|
1186
|
-
return authOp(env, AUTH_OPS.
|
|
1203
|
+
async function requestOTP(env, email) {
|
|
1204
|
+
return authOp(env, AUTH_OPS.requestOTP, { email });
|
|
1187
1205
|
}
|
|
1188
|
-
async function
|
|
1189
|
-
return authOp(env, AUTH_OPS.
|
|
1206
|
+
async function loginWithOTP(env, vars) {
|
|
1207
|
+
return authOp(env, AUTH_OPS.loginWithOTP, vars);
|
|
1190
1208
|
}
|
|
1191
|
-
async function
|
|
1192
|
-
return authOp(env, AUTH_OPS.
|
|
1209
|
+
async function refreshTokens(env, refreshToken) {
|
|
1210
|
+
return authOp(env, AUTH_OPS.refreshToken, { refreshToken });
|
|
1193
1211
|
}
|
|
1194
|
-
async function
|
|
1195
|
-
return authOp(env, AUTH_OPS.
|
|
1212
|
+
async function loginWithProvider(env, input) {
|
|
1213
|
+
return authOp(env, AUTH_OPS.loginWithProvider, { input });
|
|
1196
1214
|
}
|
|
1197
|
-
async function
|
|
1198
|
-
return authOp(env, AUTH_OPS.
|
|
1215
|
+
async function providerCallback(env, input) {
|
|
1216
|
+
return authOp(env, AUTH_OPS.providerCallback, { input });
|
|
1199
1217
|
}
|
|
1200
|
-
async function
|
|
1201
|
-
return authOp(env, AUTH_OPS.
|
|
1218
|
+
async function providerVerifyOTP(env, input) {
|
|
1219
|
+
return authOp(env, AUTH_OPS.providerVerifyOTP, { input });
|
|
1220
|
+
}
|
|
1221
|
+
function providerSignInRefusalOf(error) {
|
|
1222
|
+
if (!(error instanceof FoirRequestError)) return null;
|
|
1223
|
+
for (const entry of error.graphQLErrors ?? []) {
|
|
1224
|
+
const value = entry.extensions?.providerSignIn;
|
|
1225
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
1226
|
+
const { code, pending } = value;
|
|
1227
|
+
if (typeof code !== "string") continue;
|
|
1228
|
+
return typeof pending === "string" && pending !== "" ? { code, pending } : { code };
|
|
1229
|
+
}
|
|
1230
|
+
return null;
|
|
1231
|
+
}
|
|
1232
|
+
function signInRefusalOf(error) {
|
|
1233
|
+
if (!(error instanceof FoirRequestError)) return null;
|
|
1234
|
+
for (const entry of error.graphQLErrors ?? []) {
|
|
1235
|
+
const value = entry.extensions?.signIn;
|
|
1236
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
1237
|
+
const { code } = value;
|
|
1238
|
+
if (typeof code === "string") return { code };
|
|
1239
|
+
}
|
|
1240
|
+
return null;
|
|
1241
|
+
}
|
|
1242
|
+
async function confirmProviderLink(env, input) {
|
|
1243
|
+
return authOp(env, AUTH_OPS.confirmProviderLink, { input });
|
|
1244
|
+
}
|
|
1245
|
+
async function resendProviderLinkCode(env, input) {
|
|
1246
|
+
return authOp(env, AUTH_OPS.resendProviderLinkCode, { input });
|
|
1202
1247
|
}
|
|
1203
1248
|
async function getAuthProviders(env) {
|
|
1204
1249
|
return authOp(env, AUTH_OPS.authProviders);
|
|
@@ -1209,87 +1254,137 @@ async function getAuthConfig(env) {
|
|
|
1209
1254
|
async function getDefaultAuthProvider(env) {
|
|
1210
1255
|
return authOp(env, AUTH_OPS.defaultAuthProvider);
|
|
1211
1256
|
}
|
|
1212
|
-
async function
|
|
1213
|
-
return authOp(env, AUTH_OPS.
|
|
1257
|
+
async function signupContext(env) {
|
|
1258
|
+
return authOp(env, AUTH_OPS.signupContext);
|
|
1214
1259
|
}
|
|
1215
|
-
async function
|
|
1216
|
-
return authOp(env, AUTH_OPS.
|
|
1260
|
+
async function joinWaitlist(env, email) {
|
|
1261
|
+
return authOp(env, AUTH_OPS.joinWaitlist, { email });
|
|
1217
1262
|
}
|
|
1218
|
-
async function
|
|
1219
|
-
return authOp(env, AUTH_OPS.
|
|
1263
|
+
async function requestPasswordReset(env, email, options) {
|
|
1264
|
+
return authOp(env, AUTH_OPS.requestPasswordReset, { email, clientId: options?.clientId });
|
|
1220
1265
|
}
|
|
1221
|
-
async function
|
|
1222
|
-
return authOp(env, AUTH_OPS.
|
|
1266
|
+
async function resetPassword(env, vars) {
|
|
1267
|
+
return authOp(env, AUTH_OPS.resetPassword, vars);
|
|
1223
1268
|
}
|
|
1224
|
-
async function
|
|
1225
|
-
return authOp(env, AUTH_OPS.
|
|
1269
|
+
async function verifyEmail(env, token) {
|
|
1270
|
+
return authOp(env, AUTH_OPS.verifyEmail, { token });
|
|
1226
1271
|
}
|
|
1227
|
-
async function
|
|
1228
|
-
return authOp(env, AUTH_OPS.
|
|
1272
|
+
async function updatePassword(env, vars, options) {
|
|
1273
|
+
return authOp(env, AUTH_OPS.updatePassword, vars, options);
|
|
1229
1274
|
}
|
|
1230
1275
|
async function currentUser(env, options) {
|
|
1231
1276
|
return authOp(env, AUTH_OPS.currentUser, void 0, options);
|
|
1232
1277
|
}
|
|
1233
1278
|
async function myProviderToken(env, providerKey, options) {
|
|
1234
|
-
|
|
1279
|
+
const { forceRefresh, ...rest } = options ?? {};
|
|
1280
|
+
const vars = forceRefresh ? { providerKey, forceRefresh: true } : { providerKey };
|
|
1281
|
+
return authOp(env, AUTH_OPS.myProviderToken, vars, rest);
|
|
1235
1282
|
}
|
|
1236
|
-
async function
|
|
1237
|
-
return authOp(env, AUTH_OPS.
|
|
1283
|
+
async function logout(env, options) {
|
|
1284
|
+
return authOp(env, AUTH_OPS.logout, void 0, options);
|
|
1238
1285
|
}
|
|
1239
1286
|
async function deleteMyAccount(env, vars, options) {
|
|
1240
1287
|
return authOp(env, AUTH_OPS.deleteMyAccount, vars, options);
|
|
1241
1288
|
}
|
|
1289
|
+
async function updateMyProfile(env, change, options) {
|
|
1290
|
+
return authOp(env, AUTH_OPS.updateMyProfile, change, options);
|
|
1291
|
+
}
|
|
1292
|
+
async function myAuthorizedApps(env, options) {
|
|
1293
|
+
return authOp(env, AUTH_OPS.myAuthorizedApps, void 0, options);
|
|
1294
|
+
}
|
|
1295
|
+
async function revokeAuthorizedApp(env, id, options) {
|
|
1296
|
+
return authOp(env, AUTH_OPS.revokeAuthorizedApp, { id }, options);
|
|
1297
|
+
}
|
|
1298
|
+
async function mySessions(env, options) {
|
|
1299
|
+
return authOp(env, AUTH_OPS.mySessions, void 0, options);
|
|
1300
|
+
}
|
|
1301
|
+
async function endMySession(env, id, options) {
|
|
1302
|
+
return authOp(env, AUTH_OPS.endMySession, { id }, options);
|
|
1303
|
+
}
|
|
1304
|
+
async function signOutEverywhere(env, vars = {}, options) {
|
|
1305
|
+
return authOp(env, AUTH_OPS.signOutEverywhere, vars, options);
|
|
1306
|
+
}
|
|
1307
|
+
async function createPersonalAccessToken(env, vars, options) {
|
|
1308
|
+
return authOp(env, AUTH_OPS.createPersonalAccessToken, vars, options);
|
|
1309
|
+
}
|
|
1310
|
+
async function mySignInMethods(env, options) {
|
|
1311
|
+
return authOp(env, AUTH_OPS.mySignInMethods, void 0, options);
|
|
1312
|
+
}
|
|
1313
|
+
async function connectSignInMethod(env, vars, options) {
|
|
1314
|
+
return authOp(env, AUTH_OPS.connectSignInMethod, vars, options);
|
|
1315
|
+
}
|
|
1316
|
+
async function disconnectSignInMethod(env, provider, options) {
|
|
1317
|
+
return authOp(env, AUTH_OPS.disconnectSignInMethod, { provider }, options);
|
|
1318
|
+
}
|
|
1319
|
+
async function myFactors(env, options) {
|
|
1320
|
+
return authOp(env, AUTH_OPS.myFactors, void 0, options);
|
|
1321
|
+
}
|
|
1322
|
+
async function beginStepUp(env, password, options) {
|
|
1323
|
+
return authOp(env, AUTH_OPS.beginStepUp, { password }, options);
|
|
1324
|
+
}
|
|
1325
|
+
async function completeStepUp(env, vars, options) {
|
|
1326
|
+
return authOp(env, AUTH_OPS.completeStepUp, vars, options);
|
|
1327
|
+
}
|
|
1328
|
+
async function beginFactorEnrollment(env, vars, options) {
|
|
1329
|
+
return authOp(env, AUTH_OPS.beginFactorEnrollment, vars, options);
|
|
1330
|
+
}
|
|
1331
|
+
async function completeFactorEnrollment(env, vars, options) {
|
|
1332
|
+
return authOp(env, AUTH_OPS.completeFactorEnrollment, vars, options);
|
|
1333
|
+
}
|
|
1334
|
+
async function removeFactor(env, vars, options) {
|
|
1335
|
+
return authOp(env, AUTH_OPS.removeFactor, vars, options);
|
|
1336
|
+
}
|
|
1337
|
+
async function makeRecoveryCodes(env, elevatedHandle, options) {
|
|
1338
|
+
return authOp(env, AUTH_OPS.makeRecoveryCodes, { elevatedHandle }, options);
|
|
1339
|
+
}
|
|
1242
1340
|
async function myOrganizations(env, vars, options) {
|
|
1243
1341
|
return authOp(env, AUTH_OPS.myOrganizations, vars ?? {}, options);
|
|
1244
1342
|
}
|
|
1245
|
-
async function selectOrganization(env, vars, options) {
|
|
1246
|
-
return authOp(env, AUTH_OPS.selectMyOrganization, vars, options);
|
|
1247
|
-
}
|
|
1248
1343
|
async function registerOrganization(env, vars, options) {
|
|
1249
|
-
return authOp(env, AUTH_OPS.
|
|
1344
|
+
return authOp(env, AUTH_OPS.registerOrganization, vars, options);
|
|
1250
1345
|
}
|
|
1251
1346
|
async function saveSession(adapter, result) {
|
|
1252
1347
|
await adapter.set(TOKEN_KEY, result.token);
|
|
1253
1348
|
await adapter.set(REFRESH_KEY, result.refreshToken);
|
|
1254
|
-
if (!result.
|
|
1255
|
-
return await
|
|
1349
|
+
if (!result.userId) {
|
|
1350
|
+
return await getSessionUser(adapter) ?? { id: "", email: "" };
|
|
1256
1351
|
}
|
|
1257
|
-
await adapter.set(
|
|
1352
|
+
await adapter.set(USER_ID_KEY, result.userId);
|
|
1258
1353
|
await adapter.set(EMAIL_KEY, result.email);
|
|
1259
|
-
return { id: result.
|
|
1354
|
+
return { id: result.userId, email: result.email };
|
|
1260
1355
|
}
|
|
1261
1356
|
async function clearSession(adapter) {
|
|
1262
1357
|
await adapter.unset(TOKEN_KEY);
|
|
1263
1358
|
await adapter.unset(REFRESH_KEY);
|
|
1264
|
-
await adapter.unset(
|
|
1359
|
+
await adapter.unset(USER_ID_KEY);
|
|
1265
1360
|
await adapter.unset(EMAIL_KEY);
|
|
1266
1361
|
}
|
|
1267
1362
|
async function getSessionToken(adapter) {
|
|
1268
1363
|
return await adapter.get(TOKEN_KEY) ?? null;
|
|
1269
1364
|
}
|
|
1270
|
-
async function
|
|
1271
|
-
const id = await adapter.get(
|
|
1365
|
+
async function getSessionUser(adapter) {
|
|
1366
|
+
const id = await adapter.get(USER_ID_KEY) ?? null;
|
|
1272
1367
|
const email = await adapter.get(EMAIL_KEY) ?? null;
|
|
1273
1368
|
if (!id) return null;
|
|
1274
1369
|
return { id, email: email ?? "" };
|
|
1275
1370
|
}
|
|
1276
|
-
async function
|
|
1277
|
-
return saveSession(adapter, await
|
|
1371
|
+
async function signInWithPassword(adapter, env, vars) {
|
|
1372
|
+
return saveSession(adapter, await login(env, vars));
|
|
1278
1373
|
}
|
|
1279
|
-
async function
|
|
1280
|
-
return saveSession(adapter, await
|
|
1374
|
+
async function signUpWithPassword(adapter, env, vars) {
|
|
1375
|
+
return saveSession(adapter, await register(env, vars));
|
|
1281
1376
|
}
|
|
1282
|
-
async function
|
|
1283
|
-
return saveSession(adapter, await
|
|
1377
|
+
async function signInWithOTP(adapter, env, vars) {
|
|
1378
|
+
return saveSession(adapter, await loginWithOTP(env, vars));
|
|
1284
1379
|
}
|
|
1285
1380
|
async function resetPasswordAndSignIn(adapter, env, vars) {
|
|
1286
|
-
return saveSession(adapter, await
|
|
1381
|
+
return saveSession(adapter, await resetPassword(env, vars));
|
|
1287
1382
|
}
|
|
1288
1383
|
async function signOut(adapter, env) {
|
|
1289
1384
|
const token = await getSessionToken(adapter);
|
|
1290
1385
|
if (token) {
|
|
1291
1386
|
try {
|
|
1292
|
-
await
|
|
1387
|
+
await logout(env, { bearerToken: token });
|
|
1293
1388
|
} catch {
|
|
1294
1389
|
}
|
|
1295
1390
|
}
|
|
@@ -1299,7 +1394,7 @@ async function refreshSession(adapter, env) {
|
|
|
1299
1394
|
const refreshToken = await adapter.get(REFRESH_KEY) ?? null;
|
|
1300
1395
|
if (!refreshToken) return null;
|
|
1301
1396
|
try {
|
|
1302
|
-
const result = await
|
|
1397
|
+
const result = await refreshTokens(env, refreshToken);
|
|
1303
1398
|
await saveSession(adapter, result);
|
|
1304
1399
|
return { token: result.token, refreshToken: result.refreshToken };
|
|
1305
1400
|
} catch {
|
|
@@ -1372,20 +1467,20 @@ async function authedOp(adapter, env, op, args) {
|
|
|
1372
1467
|
}
|
|
1373
1468
|
async function requireAuth(adapter, options) {
|
|
1374
1469
|
const token = await getSessionToken(adapter);
|
|
1375
|
-
let
|
|
1376
|
-
if (token && !
|
|
1377
|
-
|
|
1470
|
+
let user = await getSessionUser(adapter);
|
|
1471
|
+
if (token && !user && options.env) {
|
|
1472
|
+
user = await recoverSessionUser(adapter, options.env, token);
|
|
1378
1473
|
}
|
|
1379
|
-
if (!token || !
|
|
1474
|
+
if (!token || !user) {
|
|
1380
1475
|
await options.onUnauthenticated();
|
|
1381
1476
|
throw new Error("[foir] onUnauthenticated must not return");
|
|
1382
1477
|
}
|
|
1383
1478
|
if (options.resolveUser) {
|
|
1384
|
-
return options.resolveUser({ token,
|
|
1479
|
+
return options.resolveUser({ token, user });
|
|
1385
1480
|
}
|
|
1386
|
-
return
|
|
1481
|
+
return user;
|
|
1387
1482
|
}
|
|
1388
|
-
async function
|
|
1483
|
+
async function recoverSessionUser(adapter, env, token) {
|
|
1389
1484
|
let me;
|
|
1390
1485
|
try {
|
|
1391
1486
|
me = await currentUser(env, { bearerToken: token });
|
|
@@ -1393,137 +1488,132 @@ async function recoverSessionCustomer(adapter, env, token) {
|
|
|
1393
1488
|
return null;
|
|
1394
1489
|
}
|
|
1395
1490
|
if (!me?.id) return null;
|
|
1396
|
-
await adapter.set(
|
|
1491
|
+
await adapter.set(USER_ID_KEY, me.id);
|
|
1397
1492
|
await adapter.set(EMAIL_KEY, me.email);
|
|
1398
1493
|
return { id: me.id, email: me.email };
|
|
1399
1494
|
}
|
|
1400
|
-
async function requireAdmin(adapter, options) {
|
|
1401
|
-
const user = await requireAuth(adapter, options);
|
|
1402
|
-
if (!user.isAdmin) {
|
|
1403
|
-
await options.onForbidden();
|
|
1404
|
-
throw new Error("[foir] onForbidden must not return");
|
|
1405
|
-
}
|
|
1406
|
-
return user;
|
|
1407
|
-
}
|
|
1408
1495
|
|
|
1409
1496
|
// src/auth/grant-table.generated.ts
|
|
1410
1497
|
var GRANT_TABLE = [
|
|
1411
|
-
["records:read",
|
|
1412
|
-
["records:create",
|
|
1413
|
-
["records:write",
|
|
1414
|
-
["records:delete",
|
|
1415
|
-
["records:publish",
|
|
1416
|
-
["records:attribute",
|
|
1417
|
-
["search:read",
|
|
1418
|
-
["embeddings:read",
|
|
1419
|
-
["embeddings:write",
|
|
1420
|
-
["schemas:read",
|
|
1421
|
-
["drafts:read",
|
|
1422
|
-
["files:read",
|
|
1423
|
-
["files:write",
|
|
1424
|
-
["files:delete",
|
|
1425
|
-
["notifications:read",
|
|
1426
|
-
["notifications:write",
|
|
1427
|
-
["notifications:consent",
|
|
1428
|
-
["pushcredentials:read",
|
|
1429
|
-
["pushcredentials:write",
|
|
1430
|
-
["notes:read",
|
|
1431
|
-
["notes:write",
|
|
1432
|
-
["notes:create",
|
|
1433
|
-
["approvals:read",
|
|
1434
|
-
["approvals:write",
|
|
1435
|
-
["rooms:read",
|
|
1436
|
-
["rooms:write",
|
|
1437
|
-
["presence:read",
|
|
1438
|
-
["operations:read",
|
|
1439
|
-
["operations:execute",
|
|
1440
|
-
["operations:write",
|
|
1441
|
-
["operations:complete",
|
|
1442
|
-
["status:write",
|
|
1443
|
-
["appconfig:read",
|
|
1444
|
-
["schedules:read",
|
|
1445
|
-
["schedules:write",
|
|
1446
|
-
["hooks:read",
|
|
1447
|
-
["hooks:write",
|
|
1448
|
-
["
|
|
1449
|
-
["
|
|
1450
|
-
["domains:read",
|
|
1451
|
-
["domains:write",
|
|
1452
|
-
["secrets:read",
|
|
1453
|
-
["secrets:list",
|
|
1454
|
-
["secrets:put",
|
|
1455
|
-
["secrets:delete",
|
|
1456
|
-
["appsecrets:read",
|
|
1457
|
-
["appsecrets:list",
|
|
1458
|
-
["appsecrets:put",
|
|
1459
|
-
["appsecrets:delete",
|
|
1460
|
-
["opsecrets:read",
|
|
1461
|
-
["opsecrets:write",
|
|
1462
|
-
["settings:read",
|
|
1463
|
-
["settings:write",
|
|
1464
|
-
["designtokens:read",
|
|
1465
|
-
["designtokens:write",
|
|
1466
|
-
["models:read",
|
|
1467
|
-
["models:write",
|
|
1468
|
-
["configs:read",
|
|
1469
|
-
["configs:write",
|
|
1470
|
-
["apps:read",
|
|
1471
|
-
["apps:write",
|
|
1472
|
-
["events:read",
|
|
1473
|
-
["targeting:debug",
|
|
1474
|
-
["visitors:forward",
|
|
1475
|
-
["apikeys:read",
|
|
1476
|
-
["apikeys:write",
|
|
1477
|
-
["organizations:read",
|
|
1478
|
-
["organizations:write",
|
|
1479
|
-
["organizations:create",
|
|
1480
|
-
["organizations:delete",
|
|
1481
|
-
["organizations:reach",
|
|
1482
|
-
["members:read",
|
|
1483
|
-
["members:write",
|
|
1484
|
-
["roles:read",
|
|
1485
|
-
["roles:write",
|
|
1486
|
-
["projects:read",
|
|
1487
|
-
["projects:write",
|
|
1488
|
-
["project:
|
|
1489
|
-
["
|
|
1490
|
-
["projects:
|
|
1491
|
-
["
|
|
1492
|
-
["tenants:
|
|
1493
|
-
["tenants:
|
|
1494
|
-
["
|
|
1495
|
-
["
|
|
1496
|
-
["
|
|
1497
|
-
["billing:
|
|
1498
|
-
["
|
|
1499
|
-
["
|
|
1500
|
-
["controlkeys:
|
|
1501
|
-
["
|
|
1502
|
-
["tenanthooks:
|
|
1503
|
-
["
|
|
1504
|
-
["
|
|
1505
|
-
["
|
|
1506
|
-
["platform:
|
|
1507
|
-
["platform:
|
|
1508
|
-
["
|
|
1509
|
-
["users:
|
|
1510
|
-
["users:
|
|
1511
|
-
["users:
|
|
1512
|
-
["users:
|
|
1513
|
-
["
|
|
1514
|
-
["identities:
|
|
1515
|
-
["
|
|
1516
|
-
["usersecrets:
|
|
1517
|
-
["usersecrets:
|
|
1518
|
-
["usersecrets:
|
|
1519
|
-
["
|
|
1520
|
-
["
|
|
1521
|
-
["signinproviders:
|
|
1498
|
+
["records:read", "model", ["own", "all"], []],
|
|
1499
|
+
["records:create", "model", [], []],
|
|
1500
|
+
["records:write", "model", ["own", "all"], []],
|
|
1501
|
+
["records:delete", "model", ["own", "all"], []],
|
|
1502
|
+
["records:publish", "model", ["own", "all"], []],
|
|
1503
|
+
["records:attribute", "model", [], []],
|
|
1504
|
+
["search:read", "model", [], []],
|
|
1505
|
+
["embeddings:read", "none", [], []],
|
|
1506
|
+
["embeddings:write", "none", [], []],
|
|
1507
|
+
["schemas:read", "none", [], []],
|
|
1508
|
+
["drafts:read", "none", [], []],
|
|
1509
|
+
["files:read", "none", ["own", "all"], []],
|
|
1510
|
+
["files:write", "none", ["own", "all"], []],
|
|
1511
|
+
["files:delete", "none", ["own", "all"], []],
|
|
1512
|
+
["notifications:read", "none", ["own", "all"], []],
|
|
1513
|
+
["notifications:write", "none", ["own", "named", "all"], []],
|
|
1514
|
+
["notifications:consent", "none", [], []],
|
|
1515
|
+
["pushcredentials:read", "none", [], []],
|
|
1516
|
+
["pushcredentials:write", "none", [], []],
|
|
1517
|
+
["notes:read", "none", ["own", "all"], []],
|
|
1518
|
+
["notes:write", "none", ["own", "all"], []],
|
|
1519
|
+
["notes:create", "none", [], []],
|
|
1520
|
+
["approvals:read", "none", [], []],
|
|
1521
|
+
["approvals:write", "none", [], []],
|
|
1522
|
+
["rooms:read", "model", [], []],
|
|
1523
|
+
["rooms:write", "model", [], []],
|
|
1524
|
+
["presence:read", "model", [], []],
|
|
1525
|
+
["operations:read", "none", [], []],
|
|
1526
|
+
["operations:execute", "operation", [], []],
|
|
1527
|
+
["operations:write", "none", [], []],
|
|
1528
|
+
["operations:complete", "none", [], []],
|
|
1529
|
+
["status:write", "none", [], []],
|
|
1530
|
+
["appconfig:read", "none", [], []],
|
|
1531
|
+
["schedules:read", "none", [], []],
|
|
1532
|
+
["schedules:write", "none", [], []],
|
|
1533
|
+
["hooks:read", "none", [], []],
|
|
1534
|
+
["hooks:write", "none", [], []],
|
|
1535
|
+
["authclients:read", "none", [], []],
|
|
1536
|
+
["authclients:write", "none", [], []],
|
|
1537
|
+
["domains:read", "none", [], []],
|
|
1538
|
+
["domains:write", "none", [], []],
|
|
1539
|
+
["secrets:read", "none", [], []],
|
|
1540
|
+
["secrets:list", "none", [], []],
|
|
1541
|
+
["secrets:put", "none", [], []],
|
|
1542
|
+
["secrets:delete", "none", [], []],
|
|
1543
|
+
["appsecrets:read", "none", [], []],
|
|
1544
|
+
["appsecrets:list", "none", [], []],
|
|
1545
|
+
["appsecrets:put", "none", [], []],
|
|
1546
|
+
["appsecrets:delete", "none", [], []],
|
|
1547
|
+
["opsecrets:read", "none", [], []],
|
|
1548
|
+
["opsecrets:write", "none", [], []],
|
|
1549
|
+
["settings:read", "none", [], []],
|
|
1550
|
+
["settings:write", "none", [], []],
|
|
1551
|
+
["designtokens:read", "none", [], []],
|
|
1552
|
+
["designtokens:write", "none", [], []],
|
|
1553
|
+
["models:read", "none", [], []],
|
|
1554
|
+
["models:write", "none", [], []],
|
|
1555
|
+
["configs:read", "none", [], []],
|
|
1556
|
+
["configs:write", "none", [], []],
|
|
1557
|
+
["apps:read", "none", [], []],
|
|
1558
|
+
["apps:write", "none", [], []],
|
|
1559
|
+
["events:read", "none", [], []],
|
|
1560
|
+
["targeting:debug", "none", [], []],
|
|
1561
|
+
["visitors:forward", "none", [], []],
|
|
1562
|
+
["apikeys:read", "none", [], []],
|
|
1563
|
+
["apikeys:write", "none", [], []],
|
|
1564
|
+
["organizations:read", "none", [], []],
|
|
1565
|
+
["organizations:write", "none", [], []],
|
|
1566
|
+
["organizations:create", "none", [], []],
|
|
1567
|
+
["organizations:delete", "none", [], []],
|
|
1568
|
+
["organizations:reach", "none", [], []],
|
|
1569
|
+
["members:read", "none", [], []],
|
|
1570
|
+
["members:write", "none", [], []],
|
|
1571
|
+
["roles:read", "none", [], []],
|
|
1572
|
+
["roles:write", "none", [], []],
|
|
1573
|
+
["projects:read", "none", [], []],
|
|
1574
|
+
["projects:write", "none", [], []],
|
|
1575
|
+
["project:stand", "none", [], []],
|
|
1576
|
+
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
1577
|
+
["projects:create", "none", [], []],
|
|
1578
|
+
["projects:delete", "none", [], []],
|
|
1579
|
+
["tenants:read", "none", [], []],
|
|
1580
|
+
["tenants:write", "none", [], []],
|
|
1581
|
+
["tenants:delete", "none", [], []],
|
|
1582
|
+
["audit:read", "none", [], []],
|
|
1583
|
+
["export:run", "none", [], []],
|
|
1584
|
+
["billing:read", "none", [], []],
|
|
1585
|
+
["billing:manage", "none", [], []],
|
|
1586
|
+
["usage:read", "none", [], []],
|
|
1587
|
+
["controlkeys:read", "none", [], []],
|
|
1588
|
+
["controlkeys:write", "none", [], []],
|
|
1589
|
+
["tenanthooks:read", "none", [], []],
|
|
1590
|
+
["tenanthooks:write", "none", [], []],
|
|
1591
|
+
["apps:install", "none", [], []],
|
|
1592
|
+
["tenant:manage", "none", [], ["project:manage", "projects:create", "projects:delete", "tenants:read", "tenants:write", "tenants:delete", "export:run", "billing:read", "billing:manage", "usage:read", "controlkeys:read", "controlkeys:write", "tenanthooks:read", "tenanthooks:write", "apps:install"]],
|
|
1593
|
+
["platform:read", "none", [], []],
|
|
1594
|
+
["platform:manage", "none", [], ["tenant:manage", "platform:read", "platform:create_workspace"]],
|
|
1595
|
+
["platform:create_workspace", "none", [], []],
|
|
1596
|
+
["users:read", "none", ["own", "named", "all"], []],
|
|
1597
|
+
["users:write", "none", ["own", "all"], []],
|
|
1598
|
+
["users:setup", "none", [], []],
|
|
1599
|
+
["users:delete", "none", ["own", "all"], []],
|
|
1600
|
+
["users:create", "none", [], []],
|
|
1601
|
+
["identities:read", "none", [], []],
|
|
1602
|
+
["identities:delete", "none", [], []],
|
|
1603
|
+
["usersecrets:read", "none", [], []],
|
|
1604
|
+
["usersecrets:list", "none", [], []],
|
|
1605
|
+
["usersecrets:put", "none", [], []],
|
|
1606
|
+
["usersecrets:delete", "none", [], []],
|
|
1607
|
+
["auth:login_with_foir", "none", [], []],
|
|
1608
|
+
["signinproviders:read", "none", [], []],
|
|
1609
|
+
["signinproviders:write", "none", [], []]
|
|
1522
1610
|
];
|
|
1523
1611
|
|
|
1524
1612
|
// src/auth/grants.ts
|
|
1525
1613
|
var WILDCARD = "*";
|
|
1526
1614
|
var RESOURCE_WILDCARD = ":*";
|
|
1615
|
+
var FIELD_PERMISSIONS = ["records:read", "records:write"];
|
|
1616
|
+
var FIELD_KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
1527
1617
|
var index;
|
|
1528
1618
|
function catalogue() {
|
|
1529
1619
|
if (!index) {
|
|
@@ -1564,15 +1654,23 @@ function parseGrant(s) {
|
|
|
1564
1654
|
let target = "";
|
|
1565
1655
|
if (rest.startsWith(":")) {
|
|
1566
1656
|
target = rest.slice(1);
|
|
1567
|
-
if (
|
|
1657
|
+
if (permission[1] === "none") return null;
|
|
1568
1658
|
if (target === "" || /[: \t\n*]/.test(target)) return null;
|
|
1659
|
+
const dot = target.indexOf(".");
|
|
1660
|
+
if (permission[1] === "model" && dot >= 0) {
|
|
1661
|
+
if (!FIELD_PERMISSIONS.includes(name) || dot === 0 || !FIELD_KEY.test(target.slice(dot + 1))) return null;
|
|
1662
|
+
}
|
|
1569
1663
|
}
|
|
1570
1664
|
return { permission, reach, target };
|
|
1571
1665
|
}
|
|
1572
1666
|
return null;
|
|
1573
1667
|
}
|
|
1574
1668
|
function covers(held, required) {
|
|
1575
|
-
|
|
1669
|
+
if (held.permission !== required.permission || reachRank[held.reach] < reachRank[required.reach]) return false;
|
|
1670
|
+
if (required.permission[1] === "model" && required.target.includes(".")) {
|
|
1671
|
+
return held.target === required.target || held.target === "" && held.reach === "all";
|
|
1672
|
+
}
|
|
1673
|
+
return held.target === "" || held.target === required.target;
|
|
1576
1674
|
}
|
|
1577
1675
|
function resourceWildcard(held) {
|
|
1578
1676
|
if (!held.endsWith(RESOURCE_WILDCARD)) return null;
|
|
@@ -1602,15 +1700,15 @@ function holds(held, required) {
|
|
|
1602
1700
|
|
|
1603
1701
|
// src/auth/access.ts
|
|
1604
1702
|
function accessFrom(who) {
|
|
1605
|
-
const
|
|
1606
|
-
if (!
|
|
1703
|
+
const user = who?.credential?.user;
|
|
1704
|
+
if (!user?.id) return null;
|
|
1607
1705
|
return {
|
|
1608
|
-
|
|
1609
|
-
roles: Array.isArray(
|
|
1706
|
+
userId: user.id,
|
|
1707
|
+
roles: Array.isArray(user.roles) ? [...user.roles] : null,
|
|
1610
1708
|
scopes: [...who?.authority?.effective ?? []]
|
|
1611
1709
|
};
|
|
1612
1710
|
}
|
|
1613
|
-
async function
|
|
1711
|
+
async function userAccess(env, options) {
|
|
1614
1712
|
return accessFrom(await authOp(env, AUTH_OPS.whoami, void 0, options));
|
|
1615
1713
|
}
|
|
1616
1714
|
async function getSessionAccess(adapter, env) {
|
|
@@ -1643,11 +1741,11 @@ function denialMessage(reason, required) {
|
|
|
1643
1741
|
case "signed_out":
|
|
1644
1742
|
return "[foir] nobody is signed in";
|
|
1645
1743
|
case "role_not_held":
|
|
1646
|
-
return `[foir] the signed-in
|
|
1744
|
+
return `[foir] the signed-in user does not hold the role "${required.role}"`;
|
|
1647
1745
|
case "roles_unknown":
|
|
1648
|
-
return `[foir] the platform did not say which roles the signed-in
|
|
1746
|
+
return `[foir] the platform did not say which roles the signed-in user holds, so "${required.role}" could not be checked`;
|
|
1649
1747
|
case "scope_not_held":
|
|
1650
|
-
return `[foir] the signed-in
|
|
1748
|
+
return `[foir] the signed-in user's scopes do not cover "${required.scope}"`;
|
|
1651
1749
|
}
|
|
1652
1750
|
}
|
|
1653
1751
|
async function requireRole(adapter, env, key) {
|
|
@@ -1665,7 +1763,7 @@ async function requireScope(adapter, env, scope) {
|
|
|
1665
1763
|
}
|
|
1666
1764
|
|
|
1667
1765
|
// src/auth/hosted.ts
|
|
1668
|
-
var DEFAULT_COOKIE_NAME = "
|
|
1766
|
+
var DEFAULT_COOKIE_NAME = "foir_session";
|
|
1669
1767
|
var DEFAULT_SESSION_PATH = "/session/token";
|
|
1670
1768
|
var DEFAULT_END_SESSION_PATH = "/session/end-session";
|
|
1671
1769
|
function hostedLoginUrl(config, returnTo) {
|
|
@@ -1721,14 +1819,14 @@ async function fetchHostedSession(request, config) {
|
|
|
1721
1819
|
} catch {
|
|
1722
1820
|
return { outcome: "unavailable", reason: "malformed", httpStatus: res.status };
|
|
1723
1821
|
}
|
|
1724
|
-
if (!json.access_token || !json.
|
|
1822
|
+
if (!json.access_token || !json.user_id) {
|
|
1725
1823
|
return { outcome: "unavailable", reason: "malformed", httpStatus: res.status };
|
|
1726
1824
|
}
|
|
1727
1825
|
return {
|
|
1728
1826
|
outcome: "active",
|
|
1729
1827
|
session: {
|
|
1730
1828
|
token: json.access_token,
|
|
1731
|
-
|
|
1829
|
+
userId: json.user_id,
|
|
1732
1830
|
email: json.email ?? "",
|
|
1733
1831
|
expiresIn: typeof json.expires_in === "number" ? json.expires_in : 0
|
|
1734
1832
|
}
|
|
@@ -1737,6 +1835,38 @@ async function fetchHostedSession(request, config) {
|
|
|
1737
1835
|
function escapeRegExp(s) {
|
|
1738
1836
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1739
1837
|
}
|
|
1838
|
+
function hostedSignInNoticeOf(location, names) {
|
|
1839
|
+
const params = location instanceof URLSearchParams ? location : location instanceof URL ? location.searchParams : new URL(location, "https://callback.invalid").searchParams;
|
|
1840
|
+
const code = params.get("foir_error") ?? (params.get("error") ? params.get("error_description") : null);
|
|
1841
|
+
if (code) {
|
|
1842
|
+
return { kind: "refused", code, message: refusalMessage(code) };
|
|
1843
|
+
}
|
|
1844
|
+
const provider = params.get("foir_connected");
|
|
1845
|
+
if (provider) {
|
|
1846
|
+
const name = names?.[provider] ?? provider;
|
|
1847
|
+
return { kind: "connected", provider, message: `Your ${name} sign-in is now connected to your account.` };
|
|
1848
|
+
}
|
|
1849
|
+
return null;
|
|
1850
|
+
}
|
|
1851
|
+
var REFUSAL_MESSAGES = {
|
|
1852
|
+
account_unavailable: "This account can\u2019t sign in right now.",
|
|
1853
|
+
account_not_here: "That account doesn\u2019t sign in here.",
|
|
1854
|
+
email_unavailable: "This app can\u2019t send email yet, so no code was sent. Sign in another way.",
|
|
1855
|
+
signup_closed: "There\u2019s no account for that address here, and it can\u2019t be made by signing in.",
|
|
1856
|
+
user_cap_reached: "This app can\u2019t take any more people right now.",
|
|
1857
|
+
provider_named_no_subject: "The provider didn\u2019t say who you are, so it can\u2019t sign you in. Try another way.",
|
|
1858
|
+
provider_has_no_issuer: "The provider didn\u2019t say who you are, so it can\u2019t sign you in. Try another way.",
|
|
1859
|
+
provider_named_no_address: "The provider didn\u2019t share an email address, so it can\u2019t sign you in. Try another way.",
|
|
1860
|
+
provider_refused: "The provider didn\u2019t finish the sign-in.",
|
|
1861
|
+
provider_unavailable: "The provider couldn\u2019t be reached. Try again in a moment.",
|
|
1862
|
+
provider_exchange_failed: "The provider couldn\u2019t be reached. Try again in a moment.",
|
|
1863
|
+
two_step_sign_in: "This account uses two-step sign-in. Sign in with your password or a passkey.",
|
|
1864
|
+
mfa_required: "This app needs a second factor, which a provider sign-in can\u2019t give. Sign in with your password instead.",
|
|
1865
|
+
sign_in_expired: "This sign-in has expired. Start again."
|
|
1866
|
+
};
|
|
1867
|
+
function refusalMessage(code) {
|
|
1868
|
+
return REFUSAL_MESSAGES[code] ?? "The sign-in couldn\u2019t be finished. Try again.";
|
|
1869
|
+
}
|
|
1740
1870
|
|
|
1741
1871
|
// src/auth/session-client.ts
|
|
1742
1872
|
var DEFAULT_SESSION_PATH2 = "/session/token";
|
|
@@ -1804,14 +1934,14 @@ function createFoirSessionClient(config) {
|
|
|
1804
1934
|
} catch {
|
|
1805
1935
|
return cached;
|
|
1806
1936
|
}
|
|
1807
|
-
if (!json.access_token || !json.
|
|
1937
|
+
if (!json.access_token || !json.user_id) return cached;
|
|
1808
1938
|
const expiresIn = typeof json.expires_in === "number" ? json.expires_in : 0;
|
|
1809
1939
|
const next = {
|
|
1810
1940
|
token: json.access_token,
|
|
1811
1941
|
expiresAt: Date.now() + expiresIn * 1e3,
|
|
1812
|
-
user: {
|
|
1942
|
+
user: { userId: json.user_id, email: json.email ?? "" }
|
|
1813
1943
|
};
|
|
1814
|
-
const changed = cached?.user.
|
|
1944
|
+
const changed = cached?.user.userId !== next.user.userId;
|
|
1815
1945
|
cached = next;
|
|
1816
1946
|
scheduleRefresh(next.expiresAt);
|
|
1817
1947
|
if (changed) emit(next.user);
|
|
@@ -1879,51 +2009,71 @@ export {
|
|
|
1879
2009
|
FoirSessionExpiredError,
|
|
1880
2010
|
authedOp,
|
|
1881
2011
|
authedRequest,
|
|
2012
|
+
beginFactorEnrollment,
|
|
2013
|
+
beginStepUp,
|
|
1882
2014
|
clearSession,
|
|
2015
|
+
completeFactorEnrollment,
|
|
2016
|
+
completeStepUp,
|
|
2017
|
+
confirmProviderLink,
|
|
2018
|
+
connectSignInMethod,
|
|
1883
2019
|
createFoirSessionClient,
|
|
2020
|
+
createPersonalAccessToken,
|
|
1884
2021
|
currentUser,
|
|
1885
|
-
customerAccess,
|
|
1886
|
-
customerJoinWaitlist,
|
|
1887
|
-
customerLogin,
|
|
1888
|
-
customerLoginOTP,
|
|
1889
|
-
customerLoginWithProvider,
|
|
1890
|
-
customerLogout,
|
|
1891
|
-
customerProviderCallback,
|
|
1892
|
-
customerProviderVerifyOTP,
|
|
1893
|
-
customerRefreshToken,
|
|
1894
|
-
customerRegister,
|
|
1895
|
-
customerRequestOTP,
|
|
1896
|
-
customerRequestPasswordReset,
|
|
1897
|
-
customerResetPassword,
|
|
1898
|
-
customerSignupContext,
|
|
1899
|
-
customerUpdatePassword,
|
|
1900
|
-
customerVerifyEmail,
|
|
1901
2022
|
deleteMyAccount,
|
|
2023
|
+
disconnectSignInMethod,
|
|
2024
|
+
endMySession,
|
|
1902
2025
|
fetchHostedSession,
|
|
1903
2026
|
getAuthConfig,
|
|
1904
2027
|
getAuthProviders,
|
|
1905
2028
|
getDefaultAuthProvider,
|
|
1906
2029
|
getSessionAccess,
|
|
1907
|
-
getSessionCustomer,
|
|
1908
2030
|
getSessionToken,
|
|
2031
|
+
getSessionUser,
|
|
1909
2032
|
hasRole,
|
|
1910
2033
|
hasScope,
|
|
1911
2034
|
hostedLoginUrl,
|
|
1912
2035
|
hostedLogoutUrl,
|
|
2036
|
+
hostedSignInNoticeOf,
|
|
2037
|
+
joinWaitlist,
|
|
2038
|
+
login,
|
|
1913
2039
|
loginWithOTP,
|
|
1914
|
-
|
|
2040
|
+
loginWithProvider,
|
|
2041
|
+
logout,
|
|
2042
|
+
makeRecoveryCodes,
|
|
2043
|
+
myAuthorizedApps,
|
|
2044
|
+
myFactors,
|
|
1915
2045
|
myOrganizations,
|
|
1916
2046
|
myProviderToken,
|
|
2047
|
+
mySessions,
|
|
2048
|
+
mySignInMethods,
|
|
2049
|
+
providerCallback,
|
|
2050
|
+
providerSignInRefusalOf,
|
|
2051
|
+
providerVerifyOTP,
|
|
1917
2052
|
refreshSession,
|
|
1918
2053
|
refreshSessionOnce,
|
|
2054
|
+
refreshTokens,
|
|
2055
|
+
register,
|
|
1919
2056
|
registerOrganization,
|
|
1920
|
-
|
|
1921
|
-
|
|
2057
|
+
removeFactor,
|
|
2058
|
+
requestOTP,
|
|
2059
|
+
requestPasswordReset,
|
|
1922
2060
|
requireAuth,
|
|
1923
2061
|
requireRole,
|
|
1924
2062
|
requireScope,
|
|
2063
|
+
resendProviderLinkCode,
|
|
2064
|
+
resetPassword,
|
|
1925
2065
|
resetPasswordAndSignIn,
|
|
2066
|
+
revokeAuthorizedApp,
|
|
1926
2067
|
saveSession,
|
|
1927
|
-
|
|
1928
|
-
|
|
2068
|
+
signInRefusalOf,
|
|
2069
|
+
signInWithOTP,
|
|
2070
|
+
signInWithPassword,
|
|
2071
|
+
signOut,
|
|
2072
|
+
signOutEverywhere,
|
|
2073
|
+
signUpWithPassword,
|
|
2074
|
+
signupContext,
|
|
2075
|
+
updateMyProfile,
|
|
2076
|
+
updatePassword,
|
|
2077
|
+
userAccess,
|
|
2078
|
+
verifyEmail
|
|
1929
2079
|
};
|