Activities of "Anjali_Musmade"

Hello smansuri Can you please share your app.module.ts & package.json so that I can reproduce the same issue. Mostly this error occurs when we don't add any service file in module file providers array. You can do one this in angular.json file if you make "sourceMap": true, in configurations with this you can check some more details of error. I am not able to reproduce please guide me if possible. Thank you

Hi Anjali,

It's not working as well. Actually the same error appier if you will generate a new project based on a microservice template with Blazor WASM by abp suite v7.4.0.

Cheers, Iulian

let me check and get back to you

Hi

to enable captcha

you follow this

https://support.abp.io/QA/Questions/489/How-to-enable-reCaptcha-in-ABP?_ga=2.177433699.75017784.1696827709-327044615.1686624402

i am confused why are you asking for angular code snippets, can you please explain?

read more about account module

https://docs.abp.io/en/commercial/latest/modules/account

All these you can override in AuthServer Project which is in mvc the previous registeration code that i share you have to put that in MVC authserver project.

read more about https://docs.abp.io/en/commercial/latest/modules/payment

if you want to do the registration in angular. you just have to do the convert the code inside RegisterLocalUserAsync() to angular which are basically httpcalls, please refer to angular documentation about how to make http requests https://angular.io/api/common/http/HttpClient

Are you really sure that you want to allow anonymous access to that?

what is the exact flow?

depending on your specific needs, you may want to create your own registration flow. Just a suggestion based on what you wrote:

Upon registration, you may create a form where you ask for the information you need to build a tenant. Create your own appservice for that, where registration alone can be done without the requirement of being logged in. When the user registrates -> you create a tenant with the information you need, based on what the user specified. First create a tenant, then create a new user in that tenant.

After that, you'll end up with a fresh tenant with a user inside. The rest can be done with an authorized user. You would not need to expose too many things.

In addition, you may want to store information about the registration state to allow for clean up scenarios.


In addition to the link you referred to: I think you can only change the permission needed, not disabling it entirely. You could try to add the [AllowAnonymous] attribute - but even if it works it would not be best practice to do that. Application Services handle specific needs. Your needs seem to be different from what the default provides. Therefore it's best to create your own implementation of Tenant/ User creation.

jfistelmann i will look into this. thanks

Hi

Yes instead of that you can create your own RegisterTenant Page in authserver and register a client with client_credentials flow

Step 1 : In OpenIddictDataSeedContributor register a client wit client_credentials flow make sure you run migrator on a empty db or delete data from the openidApplication table

  // BookStore_Web_Account
  var bookStore_Web_AccountClientId = configurationSection["BookStore_Web_Account:ClientId"];
  if (!bookStore_Web_AccountClientId.IsNullOrWhiteSpace())
  {
      var bookStore_Web_AccountClientIdRootUrl = configurationSection["BookStore_Web_Account:RootUrl"]?.TrimEnd('/');

      await CreateApplicationAsync(
          name: bookStore_Web_AccountClientId!,
          type: OpenIddictConstants.ClientTypes.Confidential,
          consentType: OpenIddictConstants.ConsentTypes.Implicit,
          displayName: "Swagger Application",
          secret: configurationSection["BookStore_Web_Account:ClientSecret"] ?? "1q2w3e*",
          grantTypes: new List<string> {OpenIddictConstants.GrantTypes.ClientCredentials },
          scopes: new List<string> { "BookStore" },
          clientUri: bookStore_Web_AccountClientIdRootUrl,
          logoUri: "/images/clients/swagger.svg",
          permissions: new List<string>
          {
              "Saas.Tenants",
              "Saas.Tenants.Create",
              "Saas.Tenants.Update",
              "Saas.Tenants.ManageConnectionStrings",
              "Saas.Tenants.SetPassword",
              "Saas.Editions",
              "Saas.Editions.Create",
              "Saas.Editions.Update"
          }
      );
  }

add this in dbmigrator appsetting.json

Step 2 Create your own RegisterTenant.cshtml create UI as it is in Register.cshtml Page in the Volo.Account.Pro module you can download the source code from abp suite.

in the RegisterTenant.cshtml.cs you can use this code make sure to create your own PostInput class just as it is in Register.cshtml.cs with the the extra fields that you need then you can use that to send it to tenant api..

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Account;
using Volo.Abp.Account.Public.Web.Pages.Account;
using Volo.Abp.Account.Public.Web.Security.Recaptcha;
using Volo.Abp.Identity.Settings;
using Volo.Abp.Settings;
using Volo.Abp.Uow;
using Volo.Saas.Host;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
using Microsoft.Extensions.Configuration;
using System.Text.Json;

namespace Acme.BookStore.Pages.Account
{
    public class RegisterTenantModel : RegisterModel
    {
        private readonly IConfiguration _configuration;

        public RegisterTenantModel(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        protected override async Task< IdentityUser > RegisterLocalUserAsync()
        {
            ValidateModel();

            var captchaResponse = string.Empty;
            if (UseCaptcha)
            {
                captchaResponse = HttpContext.Request.Form[RecaptchaValidatorBase.RecaptchaResponseKey];
            }

            string token = await GetClientCredentialsTokenAsync($"{_configuration["AuthServer:Authority"]?.EnsureEndsWith('/')}connect/token" ?? string.Empty, "BookStore_Web_Account", "1q2w3e*", new string[] { "BookStore" });




            var tenant = new
            {
                name = "demo",
                adminEmailAddress = "demo@demo.com",
                adminPassword = "Welcome1$"
            };

            var tenantId = await CreateTenant(token, JsonSerializer.Serialize(tenant));

            using (CurrentTenant.Change(tenantId))
            {
                var user = await UserManager.FindByEmailAsync("example@example.com");

                if (user == null)
                {
                    throw new UserFriendlyException("UserNotFound");
                }
                user.SetPhoneNumber("9999999999", false);
                user.Name = "Demo";
                user.Surname = "Demo";
                await UserManager.UpdateAsync(user);

                return user;
            }
        }

        private async Task< Guid? > CreateTenant(string token,string body)
        {
            using (HttpClient client = new HttpClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Post, $"{_configuration["RemoteServices:BaseUrl"]?.EnsureEndsWith('/')}api/saas/tenants");
                request.Headers.Add("Authorization", $"Bearer {token}");

                request.Content = new StringContent(body, null, "application/json");
                var response = await client.SendAsync(request);
                response.EnsureSuccessStatusCode();
                var responseBody = await response.Content.ReadAsStringAsync();
                var responseDeserilized = JsonSerializer.Deserialize<TenantResponse>(responseBody);

                return responseDeserilized?.id;
            }
        }
        private async Task< string > GetClientCredentialsTokenAsync(string tokenUrl, string clientId, string clientSecret, IEnumerable<string> scopes = null)
        {
            // Create a HttpClient to send the request to the token endpoint
            using (HttpClient client = new HttpClient())
            {
                // Set the client credentials (client_id and client_secret) in the request headers
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{clientId}:{clientSecret}")));

                // Prepare the request content for the token endpoint
                List<KeyValuePair< string, string > > requestContent = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("grant_type", "client_credentials"),
        };

                // Add scopes, if provided
                if (scopes != null)
                {
                    requestContent.Add(new KeyValuePair<string, string>("scope", string.Join(" ", scopes)));
                }

                // Send the request to the token endpoint
                HttpResponseMessage response = await client.PostAsync(tokenUrl, new FormUrlEncodedContent(requestContent));

                // Check if the request was successful (status code 200)
                if (response.IsSuccessStatusCode)
                {
                    // Read the response content (which should contain the access token)
                    string responseContent = await response.Content.ReadAsStringAsync();

                    // Deserialize the response to extract the access token
                    dynamic responseData = JObject.Parse(responseContent);
                    string accessToken = responseData.access_token;

                    return accessToken;
                }
                else
                {
                    // If the request was not successful, handle the error here
                    // You might want to log or throw an exception
                    throw new HttpRequestException($"Error getting access token. Status code: {response.StatusCode}");
                }
            }
        }

    }
    public class TenantResponse
    {
        public Guid id { get; set; }
    }
}

in this way you avoid making anything public or anonymous and only will be doable on the registeration page

Hello icoretchi,

Can you please run abp install-libs command in your project folder

check this https://support.abp.io/QA/Questions/5874

please do let me know if it helps

Thanks, Anjali

Hello srgzibrahim@gmail.com,

Please check https://medium.com/volosoft/how-to-add-a-new-javascript-library-to-your-abp-project-62b21545f4cc

Please do let me know if it helps you

Thanks, Anjali

Hello smansuri,

please do have look to similar issues https://support.abp.io/QA/Questions/702/NullInjectorError-in-console-Angular-app-couldn%27t-load https://support.abp.io/QA/Questions/773/NullInjectorError-when-access-to-Permission-features

please do let me know if find helpful

Thanks, Anjali

Hello devpayoff,

Can you please try this I was able to repro and able to run the project with the below solution.

"configurations": {
    "production": {
      "optimization": false,  // added
      "budgets": [
        {
          "type": "initial",
          "maximumWarning": "5mb", // updated
          "maximumError": "8mb" // updated
        },
        {
          "type": "anyComponentStyle",
          "maximumWarning": "2kb",
          "maximumError": "100kb"
        }
      ],
      "fileReplacements": [
        {
          "replace": "src/environments/environment.ts",
          "with": "src/environments/environment.prod.ts"
        }
      ],
      "outputHashing": "all"
    },

Hello devpayoff,

I am able to reproduce the issue at my end and working on it.

can you please share yarn.lock file by which you are able to run project successfully so that I can better assist you.

Regards,

Showing 801 to 810 of 1183 entries
Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11