How to create a new OccEndpoints in Spartacus - customization

I created a new page in Spartacus. On this page, I also wrote the necessary services to receive the data from the backend. I created a WSDTO class for my new page.
As with PDP - PLP pages when the page is opened, Google vs. I also made the fieldSetLevelMapping settings in the Network field in browsers.
But I am getting an error in spartacus because my new page in spartacus is not defined in OccEndpoint.
How can I define a new page in Spartacus like default pages in OccEndpoint.
This is how data comes in under Network in PLP. This way I want the data inside my new sheet. How can I do this?
What I did in the backend:
Populator class and Controller class are also available.
What I did in Spartacus:
ERROR :

Could you check this way?
import { OccConfig, OccEndpoint } from '#spartacus/core';
export interface YourOccEndpoints {
wishListDcatalog?: string | OccEndpoint;
}
declare module '#spartacus/core' {
interface OccEndpoints extends YourOccEndpoints {}
}
and
const yourOccEndpoints: YourOccEndpoints = {
wishListDcatalog: '...',
};
export const yourOccConfig: OccConfig = {
backend: {
occ: {
//...
endpoints: {
...yourOccEndpoints,
},
},
},
};
then provide it in your app module
provideConfig(yourOccConfig),

Related

Is there an up to date Django geolocation module that can give me countries using IP?

Is there something as simple as plug in the code and go for geolocation? I only want countries so that my website can switch to the appropriate language.
It seems that the ones I found are either deprecated, have less than 10 users, are paid/trial versions.
Faced this problem recently - indeed there are only paid options out there. However, there is an almost free solution is to use Google Cloud functions for that.
https://cloud.google.com/functions/docs/create-deploy-gcloud
Here is the code of a function you want to implement:
const cors = require('cors')
const corsOptions = {
origin: true
}
function _geolocation(req, res) {
const data = {
country: req.headers["x-appengine-country"],
region: req.headers["x-appengine-region"],
city: req.headers["x-appengine-city"],
cityLatLong: req.headers["x-appengine-citylatlong"],
userIP: req.headers["x-appengine-user-ip"],
}
res.json(data)
};
exports.geolocation = (req, res) => {
const corsHandler = cors(corsOptions);
return corsHandler(req, res, function() {
return _geolocation(req, res);
});
};
Then in the JS code of your web-page you call this function and get country from data.country.
However, if what you want is the language selection - I recommend using auto-selection of the language included in Django. Add to your middlewares:
MIDDLEWARE = [
...
'django.middleware.locale.LocaleMiddleware',
]
It will autodetect user's language based on browser settings.
More info: https://docs.djangoproject.com/en/4.1/topics/i18n/translation

Algorand WalletConnect connection not showing metadata on Pera Wallet

I'm trying to get a working connection between a NextJS application and my Algorand wallet (Pera) using WalletConnect. I am able to connect, but the NextJS application won't send any metadata like dApp name. Is there something wrong with my code?
import WalletConnect from "#walletconnect/client";
import QRCodeModal from "algorand-walletconnect-qrcode-modal";
export default function Index(props) {
// Create a connector
const connector = new WalletConnect({
bridge: "https://bridge.walletconnect.org", // Required
qrcodeModal: QRCodeModal,
clientMeta: {
description: "WalletConnect NodeJS Client",
url: "https://nodejs.org/en/",
icons: ["https://nodejs.org/static/images/logo.svg"],
name: "WalletConnect"
}
});
// Create a function to connect
let connectWallet = () => {
if (!connector.connected) {
connector.createSession()
}
// ... Event subscriptions down here ...
}
And I call the connectWallet function from a simple onClick
return (
<div>
{/* Add button to call connectWallet */}
<button onClick={() => connectWallet()}>Connect Wallet</button>
</div>
);
From what I understand, it should show the clientMeta data I send to the connector, but it just shows empty strings and no image on the Pera wallet app.
The WalletConnect documentation for Pera Wallet does not seem to indicate support of clientMeta unfortunately.
See https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0025.md and https://developer.algorand.org/docs/get-details/walletconnect/
However, it should still display the right URL.
You can compare what you see with https://algorand.github.io/walletconnect-example-dapp/ (that displays the URL https://algorand.github.io)
Small note: in general, you may get faster answers by posting Algorand-related questions on https://forum.algorand.org

Variable cookie path with ASP.NET Identity

We migrated a multitenant MVC application from ASP.NET Membership Provider to ASP.NET Identity.
This is my Startup.Auth.cs (simplified):
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity =
SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, Identity, int>(
TimeSpan.FromMinutes(30),
(manager, user) =>
manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie),
clIdentity => clIdentity.GetUserId<int>())
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
In our multitenant application, each tenant has its own 'slug' (e.g. http://example.com/tenant1/ and http://example.com/tenant2/)
However, currently, the cookies are stored in the root. This causes security issues as users from tenant1 are automatically logged in on the website from tenant2.
How can we make the CookiePath (in CookieAuthenticationOptions) variable so that it changes depending on the tenant?
I fixed this issue with a lot of help from dampee.
The CookiePath in the CookieAuthenticationOptions object is evaluated only once: at application startup.
The easiest solution (workaround) was to create a derived CookieAuthenticationProvider that overrides ResponseSignIn and ResponseSignOut.
They both have an argument called context which has a property called CookiePath. Modify this property in both of these methods to change the CookiePath.
You can also use the class I created.
Then all you have to do is replace the CookieAuthenticationProvider in the CookieAuthenticationOptions with the one you just created.
This works for the ApplicationCookie. The ExternalSignInCookie doesn't matter that much since it is used only temporarily while signing in with an external login.
Improving on SamuelDebruyn's own solution, I found you can pass the path from the SignIn call to the provider using an AuthenticationProperties object. This way, instead of extracting the path from the request context as his gist shows, you can pass it explicitly from the source:
// method inside web api controller
private void SignIn(string name, string cookiePath)
{
var claims = new[] { new Claim(ClaimTypes.Name, name) };
var identity = new ClaimsIdentity(claims, "ApplicationCookie");
var options = new AuthenticationProperties();
options.Dictionary["CustomCookiePath"] = cookiePath;
var authManager = Request.GetOwinContext().Authentication;
authManager.SignIn(options, identity);
}
// Startup.cs
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
Provider = new CustomCookieProvider()
});
// custom provider
public class CustomCookieProvider : CookieAuthenticationProvider
{
public override void ResponseSignIn(CookieResponseSignInContext context)
{
context.CookieOptions.Path = context.Properties.Dictionary["CustomCookiePath"];
base.ResponseSignIn(context);
}
}
You can use a custom ICookieManager to dynamically return the cookie value to the CookieAuthenticationProvider based on whatever is in the request, to do this you would still maintain the CookiePath as "/" and then leave it up to the ICookieManager to return (or write) the cookie however you want. The CookieManager is an option on the CookieAuthenticationOptions. I blogged about this here: http://shazwazza.com/post/owin-cookie-authentication-with-variable-cookie-paths/

How to open URL in new Browser from Silverlight Application

We have MVVM Silverlight application. I am trying to open web url from button click event which happen on client side viewmodel and through invoke method needs to open web url in new browser.
I am using Process.Start method as describe below in Server side code.
var URL = #"http://SiteSelect.aspx";
SecureString secure = new SecureString();
char[] passwordChars = Properties.Settings.Default.Password.ToCharArray();
//converting string to securestring...found from internet
foreach (char c in passwordChars)
{
secure.AppendChar(c);
}
Process.Start(URL,"",Properties.Settings.Default.User,secure,"agent");
this throws an error related to user name and password. I checked user name and password is correct. Anyone have solution or any other method I can able to use?
Thanks,
You create a helper class:
public static class CommonHelper
{
private class HyperlinkButtonWrapper : HyperlinkButton
{
public void OpenURL(string navigateUri)
{
OpenURL(new Uri(navigateUri, UriKind.Absolute));
}
public void OpenURL(Uri navigateUri)
{
base.NavigateUri = navigateUri;
base.TargetName = "_blank";
base.OnClick();
}
}
public static void OpenURL(string navigateUri)
{
new HyperlinkButtonWrapper().OpenURL(navigateUri);
}
}
Usage:
CommonHelper.OpenURL(#"http://SiteSelect.aspx");
You could use this as well :
using System.Windows.Browser;
var uri = new Uri("http://foo.fr");
HtmlPage.Window.Navigate(uri, "_blank");
Easiest way to pass credentials is to put them in the URL, however it's not very secured. Ie:
http://user:password#foo.fr

ServiceStack web services security

Hi I am new to working with Servicestack and have downloaded their very comprehensive bootstrapapi example and am working with it, but am still having some issues. The issue is with security, what is happening is I am getting 405 errors when trying to access the protected services. Using the authenticate service it appears that I am authenticating correctly. Please help and explain. Here is the code:
public class Hello
{
public string Name { get; set; }
}
public class AuthHello
{
public string Name { get; set; }
}
public class RoleHello
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
The Services:
public class HelloService : ServiceBase<Hello>
{
//Get's called by all HTTP Verbs (GET,POST,PUT,DELETE,etc) and endpoints JSON,XMl,JSV,etc
protected override object Run(Hello request)
{
return new HelloResponse { Result = "Hello, Olle är en ÖL ål " + request.Name };
}
}
[Authenticate()]
public class AuthHelloService : RestServiceBase<AuthHello>
{
public object Execute(Hello request)
{
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
[RequiredRole("Test")]
public class RoleHelloService : RestServiceBase<RoleHello>
{
public object Execute(Hello request)
{
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
Here is the AppHost:
public class HelloAppHost : AppHostBase
{
//Tell Service Stack the name of your application and where to find your web services
public HelloAppHost() : base("Hello Web Services", typeof(HelloService).Assembly) { }
public override void Configure(Container container)
{
//Register all Authentication methods you want to enable for this web app.
Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {new CustomCredentialsAuthProvider(), //HTML Form post of UserName/Password credentials
}));
container.Register<ICacheClient>(new MemoryCacheClient() { FlushOnDispose = false });
//register user-defined REST-ful urls
Routes
.Add<Hello>("/hello")
.Add<Hello>("/hello/{Name}")
.Add<AuthHello>("/AuthHello")
.Add<RoleHello>("/RoleHello");
}
}
UPDATE
Everything works as expect if you replace : RestServiceBase with : ISevice so now the question is why.
Check the wiki documentation first
I would first go through the documentation in ServiceStack's Authentication Wiki to get a better idea about how ServiceStack's Authentication works. There's a lot of documentation in the wiki, so if you're unsure of something you should refer to that first. It's a community wiki so feel free to expand whats there if you think it can help others.
Refer to the implementation in the source code if behavior is not clear
If you're unsure of what something does you should refer to the RequiredRole source code as the master authority as how it works. RequiredRole is just a Request Filter Attribute which gets run before every service that has the attribute.
The RequiredRole attribute just calls your session.HasRole() method as seen here:
public bool HasAllRoles(IAuthSession session)
{
return this.RequiredRoles
.All(requiredRole => session != null
&& session.HasRole(requiredRole));
}
Because it just calls your session you can override the implementation of session.HasRole() if you have a custom session.
Registering and Implementing a CustomUserSession
The Social BootstrapApi project does implement its own CustomSession that it registers here but does not override the HasRole() implementation so it uses the built-in implementation in the base AuthUserSession.HasRole() which simply looks like the Roles collection to see if the user has the specified role in their Session POCO:
public virtual bool HasRole(string role)
{
return this.Roles != null && this.Roles.Contains(role);
}
Session properties populated by AuthUserRepository
The Roles property (as well as most other properties on a users Session) is populated by the AuthUserRepository that you have specified e.g. if you're using the OrmLiteAuthRepository like SocialBootstrapApi does here than the Roles attribute is persisted in the Roles column in the UserAuth RDBMS table. Depending on the AuthUserRepository you use the UserAuth / UserOAuthProvider POCOs get stored as RDBMS tables in OrmLite or as text blobs in Redis, etc.
Manage roles and permissions with AssignRoles / UnAssignRoles services
So for a user to have the required role (and authorization to pass), it should have this Role added to its UserAuth db row entry. ServiceStack's AuthFeature includes 2 services for managing users permissions and roles:
/assignroles
/unassignroles
How to initially give someone the Admin Role
These services does require a user with the Admin Role to be already authenticated.
You can do this by manually changing a specific users UserAuth.Role column to include the value "Admin". The Social Bootstrap API project instead does this by handling the OnAuthenticated() event on its CustomUserSession that simply checks to see if the authenticated username is declared in the Web.Config and if it is, calls the AssignRoles service giving that authenticated user the Admin Role:
if (AppHost.Config.AdminUserNames.Contains(session.UserAuthName)
&& !session.HasRole(RoleNames.Admin))
{
var assignRoles = authService.ResolveService<AssignRolesService>();
assignRoles.Execute(new AssignRoles {
UserName = session.UserAuthName,
Roles = { RoleNames.Admin }
});
}