@bluemarble/bm-components 1.4.0 → 1.4.2

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/dist/index.mjs CHANGED
@@ -4232,6 +4232,320 @@ function useFormHelper() {
4232
4232
  });
4233
4233
  }
4234
4234
 
4235
+ // src/helpers/authHelper.ts
4236
+ import { serialize } from "cookie";
4237
+ import { parseCookies, setCookie } from "nookies";
4238
+
4239
+ // node_modules/uuid/dist/esm-node/rng.js
4240
+ import crypto from "crypto";
4241
+ var rnds8Pool = new Uint8Array(256);
4242
+ var poolPtr = rnds8Pool.length;
4243
+ function rng() {
4244
+ if (poolPtr > rnds8Pool.length - 16) {
4245
+ crypto.randomFillSync(rnds8Pool);
4246
+ poolPtr = 0;
4247
+ }
4248
+ return rnds8Pool.slice(poolPtr, poolPtr += 16);
4249
+ }
4250
+
4251
+ // node_modules/uuid/dist/esm-node/stringify.js
4252
+ var byteToHex = [];
4253
+ for (let i = 0; i < 256; ++i) {
4254
+ byteToHex.push((i + 256).toString(16).slice(1));
4255
+ }
4256
+ function unsafeStringify(arr, offset = 0) {
4257
+ return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
4258
+ }
4259
+
4260
+ // node_modules/uuid/dist/esm-node/native.js
4261
+ import crypto2 from "crypto";
4262
+ var native_default = {
4263
+ randomUUID: crypto2.randomUUID
4264
+ };
4265
+
4266
+ // node_modules/uuid/dist/esm-node/v4.js
4267
+ function v4(options, buf, offset) {
4268
+ if (native_default.randomUUID && !buf && !options) {
4269
+ return native_default.randomUUID();
4270
+ }
4271
+ options = options || {};
4272
+ const rnds = options.random || (options.rng || rng)();
4273
+ rnds[6] = rnds[6] & 15 | 64;
4274
+ rnds[8] = rnds[8] & 63 | 128;
4275
+ if (buf) {
4276
+ offset = offset || 0;
4277
+ for (let i = 0; i < 16; ++i) {
4278
+ buf[offset + i] = rnds[i];
4279
+ }
4280
+ return buf;
4281
+ }
4282
+ return unsafeStringify(rnds);
4283
+ }
4284
+ var v4_default = v4;
4285
+
4286
+ // src/helpers/authHelper.ts
4287
+ import jwt from "jsonwebtoken";
4288
+ function decodeSessionToken({
4289
+ req,
4290
+ res,
4291
+ sessionTokenName,
4292
+ validate
4293
+ }) {
4294
+ var _a;
4295
+ const token = ((_a = req.headers.authorization) == null ? void 0 : _a.split(" ")[1]) || req.cookies[sessionTokenName];
4296
+ if (!token)
4297
+ return res.status(401).json({ error: "Token inv\xE1lido", code: "token.invalid" });
4298
+ const jwtDecode = (token2) => {
4299
+ if (validate) {
4300
+ return jwt.verify(token2, process.env.JWT_SECRET);
4301
+ }
4302
+ return jwt.decode(token2);
4303
+ };
4304
+ try {
4305
+ const decoded = jwtDecode(token);
4306
+ req.user = decoded.sub;
4307
+ return;
4308
+ } catch (error) {
4309
+ return res.status(401).json({ error: "Token inv\xE1lido", code: "token.expired" });
4310
+ }
4311
+ }
4312
+ var AuthHelper = class {
4313
+ constructor({
4314
+ cookies,
4315
+ oauth,
4316
+ tokenExpTimeInSeconds,
4317
+ onLogin,
4318
+ onValidateRefreshToken,
4319
+ onInvalidateRefreshToken,
4320
+ onCreateRefreshToken,
4321
+ onGetUserData
4322
+ }) {
4323
+ this.generateJwtAndRefreshToken = (_0, ..._1) => __async(this, [_0, ..._1], function* (userId, payload = {}) {
4324
+ const token = jwt.sign(payload, process.env.JWT_SECRET, {
4325
+ subject: String(userId),
4326
+ expiresIn: this.tokenExpTimeInSeconds || 60 * 15
4327
+ // 15 minutos
4328
+ });
4329
+ const uniqueToken = v4_default();
4330
+ yield this.onCreateRefreshToken(userId, uniqueToken);
4331
+ return {
4332
+ token,
4333
+ refreshToken: uniqueToken
4334
+ };
4335
+ });
4336
+ this.invalidateCookies = (res) => {
4337
+ return res.setHeader("Set-Cookie", [
4338
+ serialize(this.cookies.sessionToken, "", {
4339
+ maxAge: -1,
4340
+ path: "/"
4341
+ }),
4342
+ serialize(this.cookies.refreshToken, "", {
4343
+ maxAge: -1,
4344
+ path: "/"
4345
+ })
4346
+ ]);
4347
+ };
4348
+ this.cookies = cookies;
4349
+ this.oauth = oauth;
4350
+ this.tokenExpTimeInSeconds = tokenExpTimeInSeconds;
4351
+ this.onLogin = onLogin;
4352
+ this.onValidateRefreshToken = onValidateRefreshToken;
4353
+ this.onInvalidateRefreshToken = onInvalidateRefreshToken;
4354
+ this.onCreateRefreshToken = onCreateRefreshToken;
4355
+ this.onGetUserData = onGetUserData;
4356
+ }
4357
+ handler(req, res) {
4358
+ return __async(this, null, function* () {
4359
+ if (!req.url)
4360
+ return res.status(400).json({ error: "url not sent" });
4361
+ if (req.url.endsWith("/login")) {
4362
+ const loginResult = yield this.onLogin(req.body);
4363
+ if (loginResult.status === "sucess") {
4364
+ const { refreshToken, token } = yield this.generateJwtAndRefreshToken(
4365
+ loginResult.userId,
4366
+ {}
4367
+ );
4368
+ setCookie({ res }, this.cookies.sessionToken, token, {
4369
+ secure: true,
4370
+ maxAge: 60 * 60 * 24 * 30,
4371
+ // 30 days
4372
+ path: "/",
4373
+ sameSite: true
4374
+ });
4375
+ setCookie({ res }, this.cookies.refreshToken, refreshToken, {
4376
+ secure: true,
4377
+ maxAge: 60 * 60 * 24 * 30,
4378
+ // 30 days
4379
+ path: "/",
4380
+ sameSite: true,
4381
+ httpOnly: true
4382
+ });
4383
+ return res.json({ token, refreshToken });
4384
+ }
4385
+ throw new HttpError(400, loginResult.response);
4386
+ }
4387
+ if (req.url.endsWith("/logout")) {
4388
+ this.invalidateCookies(res).end();
4389
+ }
4390
+ if (req.url.endsWith("/refresh")) {
4391
+ decodeSessionToken({
4392
+ req,
4393
+ res,
4394
+ sessionTokenName: this.cookies.sessionToken,
4395
+ validate: false
4396
+ });
4397
+ const userId = String(req.user);
4398
+ const refreshToken = parseCookies({ req })[this.cookies.refreshToken];
4399
+ if (!refreshToken) {
4400
+ return this.invalidateCookies(res).status(400).json({
4401
+ error: "Refresh Token n\xE3o encontrado"
4402
+ });
4403
+ }
4404
+ const isValidRefreshToken = yield this.onValidateRefreshToken(
4405
+ userId,
4406
+ refreshToken
4407
+ );
4408
+ if (!isValidRefreshToken) {
4409
+ return this.invalidateCookies(res).status(400).json({
4410
+ error: "Refresh Token inv\xE1lido"
4411
+ });
4412
+ }
4413
+ yield this.onInvalidateRefreshToken(userId, refreshToken);
4414
+ const { token, refreshToken: newRefreshToken } = yield this.generateJwtAndRefreshToken(userId, {});
4415
+ setCookie({ res }, this.cookies.sessionToken, token, {
4416
+ secure: true,
4417
+ maxAge: 60 * 60 * 24 * 30,
4418
+ // 30 days
4419
+ path: "/",
4420
+ sameSite: true
4421
+ });
4422
+ setCookie({ res }, this.cookies.refreshToken, newRefreshToken, {
4423
+ secure: true,
4424
+ maxAge: 60 * 60 * 24 * 30,
4425
+ // 30 days
4426
+ path: "/",
4427
+ sameSite: true,
4428
+ httpOnly: true
4429
+ });
4430
+ return res.json({
4431
+ token,
4432
+ refreshToken: newRefreshToken
4433
+ });
4434
+ }
4435
+ if (req.url.endsWith("/me")) {
4436
+ decodeSessionToken({
4437
+ req,
4438
+ res,
4439
+ sessionTokenName: this.cookies.sessionToken,
4440
+ validate: true
4441
+ });
4442
+ if (!req.user)
4443
+ return res.status(400).json({ error: "Usu\xE1rio n\xE3o encontrado" });
4444
+ const userData = yield this.onGetUserData(req.user);
4445
+ if (!userData)
4446
+ return res.status(400).json({ error: "Usu\xE1rio n\xE3o encontrado" });
4447
+ return res.json(userData);
4448
+ }
4449
+ if (req.url.endsWith("/oauth-url") && this.oauth) {
4450
+ const params = {
4451
+ client_id: this.oauth.client_id,
4452
+ redirect_uri: this.oauth.redirect_uri,
4453
+ scope: this.oauth.scope,
4454
+ response_type: "code",
4455
+ response_mode: "query"
4456
+ };
4457
+ const url = `https://login.microsoftonline.com/${this.oauth.tenant_id}/oauth2/v2.0/authorize?${new URLSearchParams(params)}`;
4458
+ return res.json({
4459
+ url
4460
+ });
4461
+ }
4462
+ return res.status(404).json({ error: "Route not found" });
4463
+ });
4464
+ }
4465
+ oauthSignInCallback(code) {
4466
+ return __async(this, null, function* () {
4467
+ if (!this.oauth)
4468
+ throw new Error("OAUTH variables is not defined");
4469
+ const body = {
4470
+ client_id: this.oauth.client_id,
4471
+ scope: this.oauth.scope,
4472
+ code,
4473
+ session_state: this.oauth.client_id,
4474
+ redirect_uri: this.oauth.redirect_uri,
4475
+ grant_type: "authorization_code",
4476
+ client_secret: this.oauth.client_secret
4477
+ };
4478
+ const response = yield fetch(
4479
+ `https://login.microsoftonline.com/${this.oauth.tenant_id}/oauth2/v2.0/token`,
4480
+ {
4481
+ method: "POST",
4482
+ body: new URLSearchParams(body),
4483
+ headers: { "Content-Type": "application/x-www-form-urlencoded" }
4484
+ }
4485
+ );
4486
+ const data = yield response.json();
4487
+ const decodedToken = jwt.decode(data.access_token);
4488
+ const email = decodedToken.upn;
4489
+ const fullName = `${decodedToken == null ? void 0 : decodedToken.given_name} ${decodedToken == null ? void 0 : decodedToken.family_name}`;
4490
+ return { decodedToken, email, fullName };
4491
+ });
4492
+ }
4493
+ createOauthCallbackGetServerSideProps({
4494
+ onSuccessDestination,
4495
+ onFailedDestination
4496
+ }) {
4497
+ return (ctx) => __async(this, null, function* () {
4498
+ if (!this.oauth)
4499
+ throw new Error("Oauth env variables are not defined");
4500
+ const code = ctx.query.code;
4501
+ if (!code)
4502
+ return {
4503
+ redirect: {
4504
+ permanent: false,
4505
+ destination: onFailedDestination || "/"
4506
+ }
4507
+ };
4508
+ try {
4509
+ const { fullName, email } = yield this.oauthSignInCallback(code);
4510
+ const userExists = this.onGetUserData(email);
4511
+ if (!userExists && this.oauth) {
4512
+ this.oauth.onCreateUser({ fullname: fullName, email });
4513
+ }
4514
+ const { token, refreshToken } = yield this.generateJwtAndRefreshToken(
4515
+ email,
4516
+ {}
4517
+ );
4518
+ setCookie(ctx, this.cookies.sessionToken, token, {
4519
+ secure: true,
4520
+ maxAge: 60 * 60 * 24 * 30,
4521
+ // 30 days
4522
+ path: "/"
4523
+ });
4524
+ setCookie(ctx, this.cookies.refreshToken, refreshToken, {
4525
+ secure: true,
4526
+ maxAge: 60 * 60 * 24 * 30,
4527
+ // 30 days
4528
+ path: "/",
4529
+ httpOnly: true
4530
+ });
4531
+ return {
4532
+ redirect: {
4533
+ destination: onSuccessDestination,
4534
+ permanent: false
4535
+ }
4536
+ };
4537
+ } catch (error) {
4538
+ console.log(error);
4539
+ return {
4540
+ props: {
4541
+ destination: onFailedDestination || "/"
4542
+ }
4543
+ };
4544
+ }
4545
+ });
4546
+ }
4547
+ };
4548
+
4235
4549
  // src/hooks/useGrid.ts
4236
4550
  import { useMemo as useMemo3, useState as useState6 } from "react";
4237
4551
 
@@ -4465,13 +4779,86 @@ function useEvent(event, handler, passive = false) {
4465
4779
  };
4466
4780
  });
4467
4781
  }
4782
+
4783
+ // src/contexts/AuthContext.tsx
4784
+ import React27 from "react";
4785
+ import {
4786
+ createContext as createContext3,
4787
+ useEffect as useEffect6,
4788
+ useState as useState7
4789
+ } from "react";
4790
+ import { parseCookies as parseCookies2 } from "nookies";
4791
+ function createAuthContext() {
4792
+ return createContext3({});
4793
+ }
4794
+ function CreateAuthProvider({
4795
+ api,
4796
+ children,
4797
+ sessionTokenName,
4798
+ Provider
4799
+ }) {
4800
+ const [user, setUser] = useState7();
4801
+ const [status, setStatus] = useState7("unauthenticated");
4802
+ const { createAlert } = useAlert();
4803
+ const signIn = (_0) => __async(this, [_0], function* ({ email, password }) {
4804
+ setStatus("loading");
4805
+ try {
4806
+ const response = yield api.post("/auth/login", {
4807
+ email,
4808
+ password
4809
+ });
4810
+ const { token } = response.data;
4811
+ api.defaults.headers.common.Authorization = `Bearer ${token}`;
4812
+ const { data } = yield api.get("/auth/me");
4813
+ setUser(data);
4814
+ setStatus("autenticated");
4815
+ return true;
4816
+ } catch (error) {
4817
+ createAlert(error.response.data.error, "error");
4818
+ setStatus("unauthenticated");
4819
+ throw error;
4820
+ }
4821
+ });
4822
+ function ClientSignOut() {
4823
+ return __async(this, null, function* () {
4824
+ yield api.get("/auth/logout");
4825
+ setUser(void 0);
4826
+ });
4827
+ }
4828
+ useEffect6(() => {
4829
+ const token = parseCookies2()[sessionTokenName];
4830
+ if (token) {
4831
+ setStatus("loading");
4832
+ api.get("/auth/me").then((response) => {
4833
+ setStatus("autenticated");
4834
+ setUser(response.data);
4835
+ }).catch(() => {
4836
+ setStatus("unauthenticated");
4837
+ });
4838
+ }
4839
+ }, [api, sessionTokenName]);
4840
+ return /* @__PURE__ */ React27.createElement(
4841
+ Provider,
4842
+ {
4843
+ value: {
4844
+ user,
4845
+ signOut: ClientSignOut,
4846
+ signIn,
4847
+ status
4848
+ }
4849
+ },
4850
+ children
4851
+ );
4852
+ }
4468
4853
  export {
4469
4854
  AlertContext,
4470
4855
  AlertProvider,
4471
4856
  ApiHelper,
4857
+ AuthHelper,
4472
4858
  Autocomplete2 as Autocomplete,
4473
4859
  BaseGrid,
4474
4860
  Checkbox,
4861
+ CreateAuthProvider,
4475
4862
  Dialog,
4476
4863
  EditableTableCell,
4477
4864
  FormHelperContext,
@@ -4489,6 +4876,7 @@ export {
4489
4876
  TabPanel,
4490
4877
  Td,
4491
4878
  Tr,
4879
+ createAuthContext,
4492
4880
  createFilter,
4493
4881
  filterData,
4494
4882
  getTabProps,