Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
com.chuklee.code:statetransfer
Advanced tools
Angular Universal supports state transfer from server to client; state transfer allows the server to embed startup data into the client. The Angular client can retrieve this embedded data rather than making a XHR call to the server. See https://angular.io/api/platform-browser/TransferState This is a utility library for injecting states into Angular application from within a Java application. It does not support full Angular Universal features like service injection and rendering views.
Angular Universal supports state transfer from server to client; state transfer allows the server to embed startup data into the client. The Angular client can retrieve this embedded data rather than making a XHR call to the server. See [https://angular.io/api/platform-browser/TransferState] (https://angular.io/api/platform-browser/TransferState)
This is a utility library for injecting states into Angular application from within a Java application. It does not support full Angular Universal features like service injection and rendering views.
Use case: we would like to generate a string on the server (Spring Boot) and embed that in the Angular application.
List of things to prepare
myapp
title
, user
index.html
eg. serialized_state
Generate a Spring Boot application; add Thymeleaf and Spring Web as dependencies.
Once the project has been generated update pom.xml
with the following 2 dependencies:
<dependencies>
...
<dependency>
<groupId>com.chuklee.code</groupId>
<artifactId>statetransfer</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>
This utility library uses JSON-P to hold values.
The controller should process all GET
request to either /
or /index.html
.
What this mean is that the complied Angular application should be save in static
and templates
directories.
You can remap this according to your requirements.
package com.acme;
import java.util.Date;
import com.chuklee.code.statetransfer.TransferState;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
@Controller
@RequestMapping(path={"/", "/index.html"})
public class IndexController {
@GetMapping
public String getIndex(Model model) {
// Create a state transfer object with the application id
// This id will identify the Angular application
TransferState state = new TransferState("myapp");
// Use JSON-P to create values and objects to be transferred
// TransferState can transfer any valid JSON object
// This is a object
JsonObject user = Json.createObjectBuilder()
.add("name", "wilma")
.add("email", "wilma@gmail.com")
.add("address", "1 bedrock ave")
.build();
// This is a string
JsonString title = Json.createValue("Generated on %s".formatted(new Date()));
// Add the values and objects to the state
state.add("user", user);
state.add("title", title);
// Render Angular's index.html
model.addAttribute("serialized_state", state.render());
return "index";
}
}
Now we need to compile an Angular application.
Create a new Angular application if you don't have one.
Use ng new client
to generate an angular application.
Modify the startup module (default is app.module.ts
) to import BrowserTransferStateModule
.
You will also need to register the application id.
import { NgModule } from '@angular/core';
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
// appId must be the same value when you instantiated TransferState
BrowserModule.withServerTransition({ appId: 'myapp' }),
BrowserTransferStateModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
We will transfer a string (title
) and an object (user
) from the server.
The following is an example of app.component.ts
.
import { Component, OnInit } from '@angular/core';
import {makeStateKey, TransferState} from '@angular/platform-browser';
// This is object to to be transferred from the server.
// Should match the server's structure
export interface User {
name: string
address: string
email: string
}
// Create state keys. The key names must match the server's
const stateTitleKey = makeStateKey<string>('title')
const stateUserKey = makeStateKey<User>('user')
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'client';
user: User = {
name: 'fred', address: '1 bedrock ave', email: 'fred@gmail.com'
}
// Inject TransferState service
constructor(private state: TransferState) { }
ngOnInit() {
// Get the transferred state; if the states are missing, then
// revert to default values. It is important that we should be
// able to render the view without the server states
this.title = this.state.get(stateTitleKey, 'client')
this.user = this.state.get(stateUserKey, this.user)
}
}
Access these in the view app.component.html
<h1>{{ title }}</h1>
<h2>{{ user | json }}</h2>
Add a placeholder in Angular's index.html
to serialize the state. When the final index.html
is rendered by the server side template engine, it will populate the placeholder with
serialized data.
How the placeholder is written will depend very much on which template engine you are using. In this example, I will be using (Thymeleaf)[https://www.thymeleaf.org/] specifically (inline unescaped text)[https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#inlining].
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Client</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<!-- this is the placeholder -->
[(${serialized_state})]
</head>
<body>
<app-root></app-root>
</body>
</html>
You can add the placeholder anywhere in index.html
but <head>
is probably the best
because if the application is not served from the server, then the placeholder will not
appear in your view.
Compile the Angular application with ng build
. When the build complete, you will find
the artefacts in dist/client
.
Copy the following files from Angular to Spring Boot
dist/client/index.html
to Spring Boot src/main/resources/templates
directoryindex.html
from Angular dist/client/
to src/main/resources/static
directoryRun mvn spring-boot:run
FAQs
Angular Universal supports state transfer from server to client; state transfer allows the server to embed startup data into the client. The Angular client can retrieve this embedded data rather than making a XHR call to the server. See https://angular.io/api/platform-browser/TransferState This is a utility library for injecting states into Angular application from within a Java application. It does not support full Angular Universal features like service injection and rendering views.
We found that com.chuklee.code:statetransfer demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.