for ($i = 1; $i <= 1000; $i++){ echo "Be Happy"; }

Blog

Buscar por Categorias o Tags


Cómo enviar un topic a AWS IOT con Node.js

Codigo paso a paso para conectar y enviar un topic a AWS IOT usando Node.js.

En mi canal de youtube hay un video del paso a paso:

  1. Creamos un objeto en AWS y descargamos el código de ejemplo

  2. Creamos un proyecto node
    • npm init
  3. Agregamos archivo:
    • index.js
  4. instalamos libreria
    • npm i aws-iot-device-sdk
  5. Ingresamos el codigo node:
const awsIot = require('aws-iot-device-sdk');

const today = new Date();
const date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
const time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
const dateTime = date + ' ' + time;
const topic = "topic"

const device = awsIot.device({
    clientId: 'clientId',
    host: 'host',
    port: 8883,
    keyPath: './private.key',
    certPath: './cert.pem',
    caPath: './CA.crt',
});

const IoTDevice = {
    serialNumber: "SN-D7F3C8947867",
    dateTime,
    activated: true,
    device: "MyRaspperry-01",
    type: "MySmartIoTDevice",
    payload: {}
}

const getSensorData = (cb) => getDummySensorData(cb);

const getDummySensorData = (cb) => {
    const temperatureData = { temp: '100°C', humidity: '52%' }
    return cb(temperatureData)
}

const sendData = (data) => {
    const telemetryData = {
        ...IoTDevice,
        payload: data
    }
    console.log(`STEP - Sending data to AWS  IoT Core'`, telemetryData)
    console.log(`---------------------------------------------------------------------------------`)
    return device.publish(topic, JSON.stringify(telemetryData))
}

device
    .on('connect', function () {
        console.log('STEP - Connecting to AWS  IoT Core');
        console.log(`---------------------------------------------------------------------------------`)
        setInterval(() => getSensorData(sendData), 3000)

    });

device
    .on('message', function (topic, payload) {
        console.log('message', topic, payload.toString());
    });

device
    .on('error', function (topic, payload) {
        console.log('Error:', topic, payload.toString());
    });
Comentarios  Leer Más

Cómo integrar Clean Arquitecture a Net Core 7

Codigo paso a paso para integrar Clean Arquitecture a Net Core 7.

En mi canal de youtube hay un video del paso a paso:

  1. Creamos una Blank Solution

  2. Agregamos proyecto API .Api
    • Controllers
    • Responses
  3. Agregamos proyecto Class Library .Core
    • DTOs
    • Entities
    • Enumerations
    • Interfaces
    • Exceptions
    • QueryFilters
    • Services
  4. Agregamos proyecto Class Library .Infrastructure
    • Data
    • Repositories
    • Filters
    • Mappings
    • Validators
  5. Reference
    • .API = .Core, .Infrastructure
    • .Infrastructure = .Core
  6. Ingresamos al appsettings:
    ,
    "MongoDbSettings": {
      "ConnectionString": "url",
      "DatabaseName": "namestring"
    }
    
  7. Creamos MongoDbSettingsEntity:
    public string ConnectionString { get; set; } = string.Empty;
    public string DatabaseName { get; set; } = string.Empty;
    
  8. Instalamos paquetes:
    MongoDB.Bson
    MongoDB.Driver
    Microsoft.Extensions.Options
    AspNetCore.Identity.MongoDbCore
    
  9. Agregamos al program:
    builder.Services.Configure<MongoDbSettingsEntity>(builder.Configuration.GetSection(nameof(MongoDbSettings)));
    
  10. Creamos el UserEntity:
    [BsonIgnoreExtraElements]
    public class UserEntity
    {
    [BsonId]
    [BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]
    public string Id { get; set; } = string.Empty;
    public string Username { get; set; } = string.Empty;
    public string Fullmane { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    }
    
  11. Creamos IUserRepository y IUserService:
    Task<List<UserEntity>> GetAll();
    
  12. Creamos IContext:
    IMongoCollection<UserEntity> Users { get;  }
    
  13. Creamos Context:
    public class Context : IContext
    {
    private readonly IMongoDatabase _database;
    public Context(IOptions<MongoDbSettingsEntity> options)
    {
        MongoClient _mongoClient = new MongoClient(options.Value.ConnectionString);
        _database = _mongoClient.GetDatabase(options.Value.DatabaseName);
    }
    public IMongoCollection<UserEntity> Users => _database.GetCollection<UserEntity>("users");
    }
    
  14. Creamos UserRepository:
    public class UserRepository : IUserRepository
    {
    private readonly IContext _context;
    public UserRepository(IContext context)
    {
        _context = context;
    }
    public async Task<List<UserEntity>> GetAll() => await _context.Users.Find(_ => true).ToListAsync();
    }
    
  15. Creamos UserService:
    public class UserService : IUserService
    {
    private readonly IUserRepository _userRepository;
    public UserService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }
    public Task<List<UserEntity>> GetAll()
    {
        return _userRepository.GetAll();
    }
    }
    
  16. Creamos UserService:
    public class UserService : IUserService
    {
    private readonly IUserRepository _userRepository;
    public UserService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }
    public Task<List<UserEntity>> GetAll()
    {
        return _userRepository.GetAll();
    }
    }
    
  17. Agregamos al program:
    builder.Services.AddSingleton<IUserService, UserService>();
    builder.Services.AddSingleton<IUserRepository, UserRepository>();
    
  18. Creo UserController:
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
    private readonly IUserService _userService;
    public UserController(IUserService userService)
    {
        _userService = userService;
    }
    
    // GET: api/<UserController>
    [HttpGet]
    public async Task<List<UserEntity>> GetAll()
    {
        return await _userService.GetAll();
    }
    }
    
Comentarios  Leer Más

Cómo usar EntityUser y JWT con MongoDB

Codigo paso a paso para integrar EntityUser y JWT con MongoDB.

En mi canal de youtube hay un video del paso a paso:

Instalamos paquetes:

AspNetCore.Identity.MongoDbCore
MongoDB.Bson
MongoDB.Driver
Microsoft.AspNetCore.Authentication.JwtBearer

Ingresamos al appsettings:

  ,
"MongoDbSettings": {
  "ConnectionString": "url",
  "DatabaseName": "namestring"
}

Creamos ApplicationUser:

[CollectionName("users")]
public class ApplicationUser : MongoIdentityUser<Guid>
{
    public string FullName { get; set; } = string.Empty;
}

Creamos ApplicationRole:

[CollectionName("roles")]
public class ApplicationRole : MongoIdentityRole<Guid>
{
    
}

Agregamos a Program.cs:

// Add services to the container.
builder.Services.Configure<MongoDbSettings>(builder.Configuration.GetSection(nameof(MongoDbSettings)));
BsonSerializer.RegisterSerializer(new GuidSerializer(MongoDB.Bson.BsonType.String));
BsonSerializer.RegisterSerializer(new DateTimeSerializer(MongoDB.Bson.BsonType.String));
BsonSerializer.RegisterSerializer(new DateTimeOffsetSerializer(MongoDB.Bson.BsonType.String));

//add mongoIdentityConfiguration...
var mongoDbIdentityConfig = new MongoDbIdentityConfiguration
{
    MongoDbSettings = builder.Configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>(),
    IdentityOptionsAction = options =>
    {
        options.Password.RequireDigit = false;
        options.Password.RequiredLength = 8;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireLowercase = false;

        //lockout
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.User.RequireUniqueEmail = true;
    }
};

builder.Services.ConfigureMongoDbIdentity<ApplicationUser, ApplicationRole, Guid>(mongoDbIdentityConfig)
    .AddUserManager<UserManager<ApplicationUser>>()
    .AddSignInManager<SignInManager<ApplicationUser>>()
    .AddRoleManager<RoleManager<ApplicationRole>>()
    .AddDefaultTokenProviders();

builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
    x.RequireHttpsMetadata = true;
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidIssuer = "https://localhost:5001",
        ValidAudience = "https://localhost:5001",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1swek3u4uo2u4a6e")),
        ClockSkew = TimeSpan.Zero
    };
});

builder.Services.AddSwaggerGen(setup =>
{
    // Include 'SecurityScheme' to use JWT Authentication
    var jwtSecurityScheme = new OpenApiSecurityScheme
    {
        BearerFormat = "JWT",
        Name = "JWT Authentication",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Scheme = JwtBearerDefaults.AuthenticationScheme,
        Description = "Put **_ONLY_** your JWT Bearer token on textbox below!",

        Reference = new OpenApiReference
        {
            Id = JwtBearerDefaults.AuthenticationScheme,
            Type = ReferenceType.SecurityScheme
        }
    };
    setup.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme);
    setup.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        { jwtSecurityScheme, Array.Empty<string>() }
    });
});

Creamos LoginRequest Dto:

[Required, EmailAddress]
public string Email { get; set; } = string.Empty;
[Required, DataType(DataType.Password)]
public string Password { get; set; } = string.Empty;

Creamos RegisterRequest Dto:

[Required, EmailAddress]
public string Email { get; set; } = string.Empty;
public string Username { get; set; } = string.Empty;
[Required]
public string FullName { get; set; } = string.Empty;

[Required, DataType(DataType.Password)]
public string Password { get; set; } = string.Empty;
[Required, DataType(DataType.Password), Compare(nameof(Password), ErrorMessage = "Passwords do not match")]
public string ConfirmPassword { get; set; } = string.Empty;

Creamos CreateRoleRequest Dto:

public string Role { get; set; } = string.Empty;

Creamos LoginResponse Dto:

public bool Success { get; set; }
public string AccessToken { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string UserId { get; set; } = string.Empty;
public string Message { get; set; } = string.Empty;

Creamos RegisterResponse Dto:

public string Message { get; set; } = string.Empty;
public bool Success { get; set; }

Creamos AuthenticationController:

[ApiController]
[Route("api/v1/authenticate")]
public class AuthenticationController : ControllerBase
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly RoleManager<ApplicationRole> _roleManager;

    public AuthenticationController(UserManager<ApplicationUser> userManager, RoleManager<ApplicationRole> roleManager)
    {
        _userManager = userManager;
        _roleManager = roleManager;
    }

    [HttpPost]
    [Route("roles/add")]
    public async Task<IActionResult> CreateRole([FromBody] CreateRoleRequest request)
    {
        var appRole = new ApplicationRole { Name = request.Role };
        var createRole = await _roleManager.CreateAsync(appRole);
        return Ok(new { message = "role created succesfully" });
    }

    [HttpPost]
    [Route("register")]
    public async Task<IActionResult> Register([FromBody] RegisterRequest request)
    {
        var result = await RegisterAsync(request);
        return result.Success ? Ok(result) : BadRequest(result.Message);
    }

    private async Task<RegisterResponse> RegisterAsync(RegisterRequest request)
    {
        try
        {
            var userExists = await _userManager.FindByEmailAsync(request.Email);
            if(userExists != null) return new RegisterResponse { Message = "User already exists", Success = false };

            //if we get here, no user with this email..

            userExists = new ApplicationUser
            {
                FullName = request.FullName,
                Email = request.Email,
                ConcurrencyStamp = Guid.NewGuid().ToString(),
                UserName = request.Email,

            };
            var createUserResult = await _userManager.CreateAsync(userExists, request.Password);
            if(!createUserResult.Succeeded) return new RegisterResponse { Message = $"Create user failed {createUserResult?.Errors?.First()?.Description}", Success = false };
            //user is created...
            //then add user to a role...
            var addUserToRoleResult = await _userManager.AddToRoleAsync(userExists, "USER");
            if(!addUserToRoleResult.Succeeded) return new RegisterResponse { Message = $"Create user succeeded but could not add user to role {addUserToRoleResult?.Errors?.First()?.Description}", Success = false };

            //all is still well..
            return new RegisterResponse
            {
                Success = true,
                Message = "User registered successfully"
            };
        }
        catch (Exception ex)
        {
            return new RegisterResponse { Message = ex.Message, Success = false };
        }
    }

    [HttpPost]
    [Route("login")]
    [ProducesResponseType((int) HttpStatusCode.OK , Type = typeof(LoginResponse))]
    public async Task<IActionResult> Login([FromBody] LoginRequest request)
    {
        var result = await LoginAsync(request);
        return result.Success ? Ok(result) : BadRequest(result.Message);
    }

    private async Task<LoginResponse> LoginAsync(LoginRequest request)
    {
        try
        {
            var user = await _userManager.FindByEmailAsync(request.Email);
            if (user is null) return new LoginResponse { Message = "Invalid email/password", Success = false };

            //all is well if ew reach here
            var claims = new List<Claim>
        {
            new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
            new Claim(ClaimTypes.Name, user.UserName),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
        };
            var roles = await _userManager.GetRolesAsync(user);
            var roleClaims = roles.Select(x => new Claim(ClaimTypes.Role, x));
            claims.AddRange(roleClaims);

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("1swek3u4uo2u4a6e"));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expires = DateTime.Now.AddMinutes(30);

            var token = new JwtSecurityToken(
                issuer: "https://localhost:5001",
                audience: "https://localhost:5001",
                claims: claims,
                expires: expires,
                signingCredentials: creds
                );

            return new LoginResponse
            {
                AccessToken = new JwtSecurityTokenHandler().WriteToken(token),
                Message = "Login Successful",
                Email = user?.Email,
                Success = true,
                UserId = user?.Id.ToString()
            };
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return new LoginResponse { Success = false, Message = ex.Message };
        }
    }
}

Agregamos [Authorize]

Comentarios  Leer Más

Cómo agregar un contador de balas en Roblox Studio

Codigo para agregar un contador de balas en Roblox Studio usando el (ACS) Advanced Combat System.

En mi canal de youtube hay un video del paso a paso:

Editar linea 1511 en StarterPlayer/StarterCharacterScripts/ACS_Client/ACS_Framework

	if WeaponData.ShootType == 1 then
		HUD.FText.Text = Ammo.."/"..StoredAmmo.." | Semi"
	elseif WeaponData.ShootType == 2 then
		HUD.FText.Text = Ammo.."/"..StoredAmmo.." | Burst"
	elseif WeaponData.ShootType == 3 then
		HUD.FText.Text = Ammo.."/"..StoredAmmo.." | Auto"
	elseif WeaponData.ShootType == 4 then
		HUD.FText.Text = Ammo.."/"..StoredAmmo.." | Pump-Action"
	elseif WeaponData.ShootType == 5 then
		HUD.FText.Text = Ammo.."/"..StoredAmmo.." | Bolt-Action"
	end
Comentarios  Leer Más

Cómo crear y configurar prueba unitaria Jest en React con Vite y Typescript

Paso a paso para crear una prueba unitaria basica con Jest en React con Vite y Typescript.

En mi canal de youtube hay un video del paso a paso:

yarn add --dev jest babel-jest @babel/preset-env @babel/preset-react 
yarn add --dev @testing-library/react @testing-library/dom @testing-library/user-event @types/jest jest-environment-jsdom
yarn add --dev jest-svg-transformer
pnpm i --save-dev @babel/core @babel/preset-typescript
pnpm i --save-dev identity-obj-proxy

"test": "jest --watchAll=false --coverage --CI=true"

babel.config.js 
module.exports = {
    presets: [
        [ '@babel/preset-env', { targets: { esmodules: true } } ],
        [ '@babel/preset-react', { runtime: 'automatic' } ],
        '@babel/preset-typescript',
    ],
};

jest.config.js
module.exports = {
    testEnvironment: 'jest-environment-jsdom',
    setupFiles: ['./jest.setup.js'],
    moduleNameMapper: {
        "^.+\\.svg$": "jest-svg-transformer",
	"\\.(css|less|scss)$": "identity-obj-proxy",
  }
}

jest.setup.js

App.test.tsx
import { render, screen } from '@testing-library/react';
import App from '../App';

test('Renders main page correctly', async () => {
  render(<App />);
  const buttonCount = await screen.findByRole('button');
  expect(buttonCount.innerHTML).toBe('count is 0');
  expect(true).toBeTruthy();
});
Comentarios  Leer Más