Couchbase Lite pull replication - couchbase

I've got android and web apps. Android app uses Couchbase Lite, web app uses Couchbase. I'm using Couchbase Sync Gateway to enable data replication between those two databases.
So far it works ok for sending data from mobile and receiving it both in web app and second mobile device. I noticed that all send documents have "_sync" parameter added.
My question is how can I enable documents added through web app (to couchbase database) to take part in replication? (they don't have field "_sync" by default)
edit
As Legendary_Hunter suggested I tried using Shadow, but still can't get it working. My config file:
{
"log":["CRUD+", "REST+", "Changes+", "Attach+"],
"databases": {
"kris_mobile_db": {
"server":"http://192.168.0.11:8091",
"sync":`
function (doc) {
channel (doc.channels);
}`,
"bucket":"kris_mobile_db",
"users": {
"GUEST": {
"disabled": false,
"admin_channels": ["*"]
}
},
"shadow": {
"server": "http://localhost:8091",
"bucket": "kris_mobile_db_sync"
}
}
}
}
edit2 (29.05.16)
public class DatabaseManager {
private static DatabaseManager manager;
private static CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder().autoreleaseAfter(6000).build();
private static String bucketName = "kris_mobile_db";
private Cluster cluster;
private Bucket bucket;
public static DatabaseManager getInstance(){
if(manager == null)
manager = new DatabaseManager();
return manager;
}
public Bucket getBucketInstance(){
if(bucket == null)
bucket = cluster.openBucket(bucketName);
return bucket;
}
public boolean establishConnection(String host, String port, String bucketName){
// host: 192.168.0.11, port: 8091
cluster = CouchbaseCluster.create(env, host+":"+port);
DatabaseManager.bucketName = bucketName;
bucket = cluster.openBucket(bucketName);
return true;
}
}
and inserting is like
JsonDocument doc = JsonDocument.create(docId, content);
DatabaseManager.getInstance().getBucketInstance().insert(doc);
edit3
So finally I managed to get shadowing working. If anyone had the same problem. My basic database is kris_mobile_db and syncGateway shadowing database is kris_mobile_db_sync. Config file:
{
"log":["CRUD+", "REST+", "Changes+", "Attach+"],
"databases": {
"kris_mobile_db": {
"server":"http://192.168.0.11:8091",
"sync":`
function (doc) {
channel (doc.channels);
}`,
"bucket":"kris_mobile_db_sync",
"users": {
"GUEST": {
"disabled": false,
"admin_channels": ["*"]
}
},
"shadow":{
"server":"http://192.168.0.11:8091",
"bucket":"kris_mobile_db"
}
}
}
}

Just use bucket shadowing. It is bidirectional syncing of sync gateway bucket with any bucket of couchbase server.

If you want to keep all the good things that the Sync Function gives you, than you have to go through the sync gateway. The sync gateway exposes a REST API that you can use to build your web app.

Related

How can i setup private proxy for a webdriver session?

Im using chromedriver to be specific and not involved in any code.
I've tried to sent post request directly to chromedriver to create new session and successfully configured them with a public proxy (no authentication), but it didn't seem to work when i switch to a private one (still can access to the internet and ip remains the same as my PC). Of course, I guaranteed that my private proxy and its authentication are valid and working.
My private proxy infos: IPv4, HTTP, auth with username and password.
And here is how i formatted the request's body with
Public proxy:
{
"capabilities": {
"alwaysMatch": {
"goog:chromeOptions": {
"w3c": true,
"excludeSwitches": [
"enable-automation"
]
},
"proxy": {
"proxyType": "manual",
"httpProxy": "ip:port"
}
}
}
}
Private proxy:
{
"capabilities": {
"alwaysMatch": {
"goog:chromeOptions": {
"w3c": true,
"excludeSwitches": [
"enable-automation"
]
},
"proxy": {
"proxyType": "manual",
"httpProxy": "username:password#ip:port"
}
}
}
}
I've also tried to use "http://username:password#ip:port".
Is the "httpProxy" property being wrongly formatted?
Edit: the driver accept the private proxy without providing username:password but prompted to enter them later on. But are there any workarounds to automatically login by simply using some kind of url scheme like username:password#ip:port?

How to get access to specific metadata of a ERC721 token

I would like to get n ERC721 token with a specific "dna".
See the metadata below:
{
"dna": "602472F",
"name": "Test #1",
"description": "My Collectibles",
"image": "ipfs://QmasMm8v9WkU11BtnWsybDW6/1.png",
"edition": 1,
"attributes": [
{
"trait": "type",
"value": "Fire"
},
{
"trait_type": "Eyes",
"value": "Black"
}
]
}
I know how to access a token using tokenURI.
Here is my code:
string public uri;
string public uriSuffix = ".json";
function _baseURI() internal view virtual override returns (string memory) {
return uri;
}
function tokenURI(uint256 _tokenId) public view virtual override returns (string memory){
require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory currentBaseURI = _baseURI();
return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, _tokenId.toString(), uriSuffix)) : "";
}
Now, how can I check if a token has the dna I am looking for? Should I get this info from Opensea API or from the solidity side?
Ps: All my .json and .png files are hosted in IPFS.
EVM contracts are not able to read offchain data (the JSON file) directly. You'd need to use an offchain app (or an oracle provider such as Chainlink) for that to feed the offchain data to the contract.
So it's much easier to just query the data from an offchain app.
Example using node.js and the web3 package for querying the contract:
const contract = new web3.eth.Contract(abiJson, contractAddress);
const tokenURI = await contract.methods.tokenURI(tokenId);
const contents = (await axios.get(tokenURI)).data;
return contents.dna;

How to check and store whether user is logged in correctly?

Is there a better way of checking whether a user is logged in? Because I use the following approach for multiple apps and serving them somehow causes disparities, since it confuses the current app's item with other app's items.
I check whether a user is logged in like this:
constructor(private afAuth: AngularFireAuth, private router: Router, private db: AngularFirestore) {
this.userData = new ReplaySubject<UserDetails>();
afAuth.auth.onAuthStateChanged(user => {
if (user) {
this.user = user;
const local = localStorage.getItem('user');
if (local !== null) {
this.userData.next(JSON.parse(localStorage.getItem('user')));
} else {
this.fetchUserData();
}
} else {
localStorage.setItem('user', null);
}
});
}
get isLoggedIn(): boolean {
const user = localStorage.getItem('user');
return user !== 'null';
}
If each app is served from its own domain, then each will have its own localStorage and there can't be any conflict/confusion between them.
If you're serving multiple apps from the same domain, you'll have to use a unique name in the local storage for each app. Something like localStorage.setItem('app1_user', null) vs localStorage.setItem('app2_user', null).
But note that Firebase Authentication only has a single authenticated user per domain. So if you're serving multiple apps from the same domain, the user is (according to Firebase Authentication) signed in to all of them (or to none of them) at the same time.

Passing data to SignalR Hub using Post method to Web Api returned: The remote server returned an error: (404) Not Found

Recently, I just started to learn on SignalR and I had been testing on one project that I found on GitHub. However I did stuck when trying to Post data to Web api part.
I just get everything done yet I cannot really make this project to work somehow. This is basically the program for the project. It is a console app and did send the data(Json) to Web Api
// Get the stuff we need to send
GetMetrics(out cpuTime, out memUsage, out totalMemory);
// Send the data
var postData = new
{
MachineName = System.Environment.MachineName,
Processor = cpuTime,
MemUsage = memUsage,
TotalMemory = totalMemory
};
var json = JsonConvert.SerializeObject(postData);
// Post the data to the server http://localhost:80/api/cpuinfo
var serverUrl = new Uri(ConfigurationManager.AppSettings["ServerUrl"]);
var client = new WebClient();
client.Headers.Add("Content-Type", "application/json");
client.UploadString(serverUrl, json);
Moving to web part. I did have the Asp.net MVC and did create the RouteConfig inside the App_Start to route HTTP request to controller.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
And this is the controller class.
public class CpuInfoController : ApiController
{
public void Post(CpuInfoPostData cpuInfo)
{
var context = GlobalHost.ConnectionManager.GetHubContext<CpuInfo>();
context.Clients.All.cpuInfoMessage(cpuInfo.MachineName, cpuInfo.Processor, cpuInfo.MemUsage, cpuInfo.TotalMemory);
}
}
I also had it registered inside Global.asax as below
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
After done all this, I still cant get this done and my console application pop up some errors as in the image here. It seems like the api/cpuinfo was not found.
Please advice me if anything that I had done wrong here.
The full version of this project can be found here.
You have to modify the File App.config in "CpuInfoClient" project. (the value of the Key)
Use "http" instead of "https"
Change the port number to the actual port number (instead of 44300), that uses the web application after starting. The exact port for the substitution you can see , when the web app starts in IE or Firefox. The port is also in "WcfCpuApp -> Properties -> Web -> Project-URL
Be sure that your web application is running, when you start "CpuInfoClient"

Sending credentials in url is not supported in chrome 59

I have a basic authentication for a SSRS report server, to avoid the login pop up window while hitting a SSRS report server from a web server. I'm sending the credentials in url itself. It was working upto google chrome 58, but now it is updated to chrome 59. Now i'm not able to send credentials in the browser url.
Example https://gooduser:secretpassword#www.example.co
username : gooduser
password : secredpassword
Kindly help on this please!
I solve the same problem with chrome extension.
In extension background.js
chrome.extension.onMessage.addListener( function(request, sender, sendResponse){
chrome.webRequest.onAuthRequired.addListener(
function(details, callbackFn) {
console.log("onAuthRequired!", details, callbackFn);
callbackFn({
authCredentials: {username: request.username, password: request.password }
});
},
{urls: request.url + "/*"]},
['asyncBlocking']
);
});
in extension contentscript.js
window.addEventListener("message", function(event) {
if ( event.type == "BASIC_AUTH" ) {
chrome.runtime.sendMessage(
event.data,
event.data.sender,
function (response) {}
);
}
});
in HTML javascript
window.postMessage({ type: "BASIC_AUTH", url:"www.mydomain.com", username:"myusername", password:"mypassword" }, "*");
If you like use extensions from Chrome Web Store like : MultiPass for HTTP basic authentication
You can use the "MultiPass for HTTP basic authentication" Chrome Extension to handle this.
You can do via GitHub MultiPass for HTTP basic authentication
(or)
Download the extension from Chrome Web Store - MultiPass Chrome Extension
(Or)
Download the extension as crx. You can get it as crx from chrome-extension-downloader
Once you download the Extension as crx File - Configuring the same into your Test/Source is very simple.
And this can be tested using the Sample Basic Auth-Site.
public class ChromeAuthTest {
WebDriver driver;
public ChromeAuthTest() {
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
}
private void initDriver() {
ChromeOptions cOptions = new ChromeOptions();
cOptions.addExtensions(new File("MultiPass-for-HTTP-basic-authentication_v.crx"));
driver = new ChromeDriver(cOptions);
configureAuth(
"https://the-internet.herokuapp.com/basic_auth",
"admin",
"admin");
}
private void configureAuth(String url, String username, String password) {
driver.get("chrome-extension://enhldmjbphoeibbpdhmjkchohnidgnah/options.html");
driver.findElement(By.id("url")).sendKeys(url);
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
driver.findElement(By.className("credential-form-submit")).click();
}
public void doTest() {
initDriver();
driver.get("https://the-internet.herokuapp.com/basic_auth");
System.out.println(driver.getTitle());
driver.quit();
}
public static void main(String[] args) {
new ChromeAuthTest().doTest();
}
}
NOTE: This is taken from this Answer.
Hope this helps!