uhm ... everything
This commit is contained in:
parent
c6e9c08a36
commit
35d0d3ca8d
28 changed files with 1216 additions and 1 deletions
|
@ -1,6 +1,6 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'org.springframework.boot' version '3.0.6'
|
id 'org.springframework.boot' version '3.1.0'
|
||||||
id 'io.spring.dependency-management' version '1.1.0'
|
id 'io.spring.dependency-management' version '1.1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,14 @@ dependencies {
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||||
implementation 'org.springframework.session:spring-session-core'
|
implementation 'org.springframework.session:spring-session-core'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
|
implementation 'org.springframework.session:spring-session-core'
|
||||||
|
implementation 'org.springframework.session:spring-session-jdbc'
|
||||||
runtimeOnly 'com.h2database:h2'
|
runtimeOnly 'com.h2database:h2'
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
|
|
||||||
|
implementation("com.github.ua-parser:uap-java:1.5.4")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||||
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||||
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||||
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||||
|
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;
|
||||||
|
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableJdbcHttpSession
|
||||||
|
public class Config extends AbstractHttpSessionApplicationInitializer {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EmbeddedDatabase dataSource() {
|
||||||
|
return new EmbeddedDatabaseBuilder()
|
||||||
|
.setType(EmbeddedDatabaseType.H2)
|
||||||
|
.addScript("org/springframework/session/jdbc/schema-h2.sql").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PlatformTransactionManager transactionManager(DataSource dataSource) {
|
||||||
|
return new DataSourceTransactionManager(dataSource);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,17 @@
|
||||||
package de.unileipzig.datenschutz.paper10.demo;
|
package de.unileipzig.datenschutz.paper10.demo;
|
||||||
|
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.dto.ScreenSizeData;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class FingerprinitngDemoApplication {
|
public class FingerprinitngDemoApplication {
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo;
|
||||||
|
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.data.FontsFingerprint;
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.data.ScreenSizeFinerPrint;
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.data.UserSession;
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.data.UserSessionRepo;
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.dto.FontList;
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.dto.FontListDto;
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.dto.ScreenSizeData;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class UserBackController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserSessionRepo userSessionRepo;
|
||||||
|
|
||||||
|
@PostMapping("/screensize")
|
||||||
|
public void receiveScreenSizeData(@RequestBody ScreenSizeData screenSizeData,
|
||||||
|
final HttpSession session) {
|
||||||
|
Optional<UserSession> userSession = userSessionRepo.findBySessionID(session.getId());
|
||||||
|
|
||||||
|
if (userSession.isEmpty()){
|
||||||
|
UserSession newSession = new UserSession(session.getId());
|
||||||
|
userSession = Optional.of(userSessionRepo.save(newSession));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userSession.get().getScreenSizeFinerPrint() == null){
|
||||||
|
ScreenSizeFinerPrint screenSizeFinerPrint = new ScreenSizeFinerPrint(screenSizeData.getScreenSize().getWidth(), screenSizeData.getScreenSize().getHeight());
|
||||||
|
userSession.get().setScreenSizeFinerPrint(screenSizeFinerPrint);
|
||||||
|
userSessionRepo.save(userSession.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/fonts")
|
||||||
|
public void receiveFontsData(@RequestBody Object object,
|
||||||
|
final HttpSession session){
|
||||||
|
|
||||||
|
FontList fontList = FontListDto.parseToFontList(object);
|
||||||
|
|
||||||
|
Optional<UserSession> userSession = userSessionRepo.findBySessionID(session.getId());
|
||||||
|
|
||||||
|
if (userSession.isEmpty()){
|
||||||
|
UserSession newSession = new UserSession(session.getId());
|
||||||
|
userSession = Optional.of(userSessionRepo.save(newSession));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userSession.get().getFontsFingerprint() == null){
|
||||||
|
FontsFingerprint fontsFingerprint = new FontsFingerprint(fontList.getInstalledFonts());
|
||||||
|
userSession.get().setFontsFingerprint(fontsFingerprint);
|
||||||
|
userSessionRepo.save(userSession.get());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo;
|
||||||
|
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.data.*;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
import ua_parser.Parser;
|
||||||
|
import ua_parser.Client;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class UserFrontController {
|
||||||
|
|
||||||
|
private static final Parser uaParser = new Parser();
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
UserSessionRepo userSessionRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ScreenSizeFinerPrintRepo screenSizeFinerPrintRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FontsFingerprintRepo fontsFingerprintRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FontsDataRepo fontsDataRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HeaderFingerprintRepo headerFingerprintRepo;
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index(final HttpServletRequest request,
|
||||||
|
final HttpSession session,
|
||||||
|
final Model model){
|
||||||
|
|
||||||
|
Optional<UserSession> userSession = userSessionRepo.findBySessionID(session.getId());
|
||||||
|
|
||||||
|
if (userSession.isEmpty()){
|
||||||
|
UserSession newSession = new UserSession(session.getId());
|
||||||
|
userSession = Optional.of(userSessionRepo.save(newSession));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userSession.get().getHeaderFingerprint() == null){
|
||||||
|
userSession.get().setHeaderFingerprint(parseHeader(request));
|
||||||
|
userSessionRepo.save(userSession.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
addModelData(model, userSession.get());
|
||||||
|
|
||||||
|
return "main";
|
||||||
|
}
|
||||||
|
private static HeaderFingerprint parseHeader(final HttpServletRequest request){
|
||||||
|
|
||||||
|
Client c = uaParser.parse(request.getHeader("user-agent"));
|
||||||
|
|
||||||
|
return new HeaderFingerprint(
|
||||||
|
c.os.family,
|
||||||
|
c.os.major,
|
||||||
|
c.os.minor,
|
||||||
|
c.device.family,
|
||||||
|
c.userAgent.family,
|
||||||
|
c.userAgent.major,
|
||||||
|
c.userAgent.minor,
|
||||||
|
Arrays.stream(request.getHeader("accept").split("[,;]")).collect(Collectors.toSet()),
|
||||||
|
Arrays.stream(request.getHeader("accept-encoding").split(", ")).collect(Collectors.toSet()),
|
||||||
|
Arrays.stream(request.getHeader("accept-language").split("[,;]")).collect(Collectors.toSet())
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addModelData(final Model model,
|
||||||
|
UserSession userSession){
|
||||||
|
|
||||||
|
model.addAttribute("session_id", userSession.getSessionID());
|
||||||
|
|
||||||
|
if (userSession.getScreenSizeFinerPrint() != null){
|
||||||
|
model.addAttribute("show_screen_size", true);
|
||||||
|
model.addAttribute("screenSizeFinerPrint_width", userSession.getScreenSizeFinerPrint().getWidth());
|
||||||
|
model.addAttribute("screenSizeFinerPrint_width_count", screenSizeFinerPrintRepo.findAllByWidthEquals(userSession.getScreenSizeFinerPrint().getWidth()).size()/2-1);
|
||||||
|
model.addAttribute("screenSizeFinerPrint_height", userSession.getScreenSizeFinerPrint().getHeight());
|
||||||
|
model.addAttribute("screenSizeFinerPrint_height_count", screenSizeFinerPrintRepo.findAllByHeightEquals(userSession.getScreenSizeFinerPrint().getHeight()).size()/2-1);
|
||||||
|
}
|
||||||
|
if (userSession.getFontsFingerprint() != null) {
|
||||||
|
model.addAttribute("show_fonts", true);
|
||||||
|
model.addAttribute("fontsFingerprint_installedFonts", new FontsModel().generateFontsModelSet(userSession.getFontsFingerprint().getInstalledFonts()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userSession.getHeaderFingerprint() != null) {
|
||||||
|
model.addAttribute("show_header", true);
|
||||||
|
HeaderFingerprint headerFingerprint = userSession.getHeaderFingerprint();
|
||||||
|
model.addAttribute("headerFingerprint_os_type", headerFingerprint.getOsType());
|
||||||
|
model.addAttribute("headerFingerprint_os_type_count", headerFingerprintRepo.findByOsTypeIs(headerFingerprint.getOsType()).size()-1);
|
||||||
|
model.addAttribute("headerFingerprint_os_version", headerFingerprint.getOsVersion());
|
||||||
|
model.addAttribute("headerFingerprint_os_version_count", headerFingerprintRepo.findByOsTypeIsAndOsVersionIs(headerFingerprint.getOsType(), headerFingerprint.getOsVersion()).size()-1);
|
||||||
|
model.addAttribute("headerFingerprint_os_sub_version", headerFingerprint.getOsSubVersion());
|
||||||
|
model.addAttribute("headerFingerprint_os_sub_version_count", headerFingerprintRepo.findByOsTypeIsAndOsVersionIsAndOsSubVersionIs(headerFingerprint.getOsType(), headerFingerprint.getOsVersion(), headerFingerprint.getOsSubVersion()).size()-1);
|
||||||
|
model.addAttribute("headerFingerprint_device", headerFingerprint.getDevice());
|
||||||
|
model.addAttribute("headerFingerprint_device_count", headerFingerprintRepo.findByDeviceIs(headerFingerprint.getDevice()).size()-1);
|
||||||
|
model.addAttribute("headerFingerprint_useragent_family", headerFingerprint.getUseragentFamily());
|
||||||
|
model.addAttribute("headerFingerprint_useragent_family_count", headerFingerprintRepo.findByUseragentFamilyIs(headerFingerprint.getUseragentFamily()).size()-1);
|
||||||
|
model.addAttribute("headerFingerprint_useragent_family_version", headerFingerprint.getUseragentVerison());
|
||||||
|
model.addAttribute("headerFingerprint_useragent_family_version_count", headerFingerprintRepo.findByUseragentFamilyIsAndUseragentVerisonIs(headerFingerprint.getUseragentFamily(), headerFingerprint.getUseragentVerison()).size()-1);
|
||||||
|
model.addAttribute("headerFingerprint_useragent_family_sub_version", headerFingerprint.getUseragentSubVersion());
|
||||||
|
model.addAttribute("headerFingerprint_useragent_family_sub_version_count", headerFingerprintRepo.findByUseragentFamilyIsAndUseragentVerisonIsAndUseragentSubVersionIs(headerFingerprint.getUseragentFamily(), headerFingerprint.getUseragentVerison(), headerFingerprint.getUseragentSubVersion()).size()-1);
|
||||||
|
model.addAttribute("headerFingerprint_accepts", headerFingerprint.getAccepts().toString());
|
||||||
|
//model.addAttribute("headerFingerprint_accepts_count", filterAcceptsEquals(headerFingerprint.getAccepts(), headerFingerprintRepo.findAllByAcceptsIn(headerFingerprint.getAccepts())));
|
||||||
|
model.addAttribute("headerFingerprint_encoding", headerFingerprint.getEncoding().toString());
|
||||||
|
//model.addAttribute("headerFingerprint_encoding_count", filterAcceptsEquals(headerFingerprint.getEncoding(), headerFingerprintRepo.findAllByEncodingIn(headerFingerprint.getEncoding())));
|
||||||
|
model.addAttribute("headerFingerprint_languages", headerFingerprint.getLanguages().toString());
|
||||||
|
//model.addAttribute("headerFingerprint_languages_count", filterAcceptsEquals(headerFingerprint.getLanguages(), headerFingerprintRepo.findAllByLanguagesIs(headerFingerprint.getLanguages())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class FontsModel {
|
||||||
|
private final String name;
|
||||||
|
private final int count;
|
||||||
|
|
||||||
|
public FontsModel(){
|
||||||
|
|
||||||
|
name = null;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontsModel(String name, int count){
|
||||||
|
this.name = name;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<FontsModel> generateFontsModelSet(Set<FontsData> usableFonts){
|
||||||
|
FontsData[] ordered = usableFonts.toArray(FontsData[]::new);
|
||||||
|
Arrays.sort(ordered, Comparator.comparing(FontsData::getFont));
|
||||||
|
ArrayList<FontsModel> ret = new ArrayList<>();
|
||||||
|
for (FontsData font : ordered)
|
||||||
|
ret.add(new FontsModel(
|
||||||
|
font.getFont(),
|
||||||
|
font.getPartOf().size()-1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
|
||||||
|
public interface FingerprintRepo extends CrudRepository<ScreenSizeFinerPrint, Long> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.ManyToMany;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class FontsData {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
String font;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "installedFonts")
|
||||||
|
private Set<FontsFingerprint> partOf;
|
||||||
|
|
||||||
|
FontsData(){
|
||||||
|
|
||||||
|
}
|
||||||
|
public FontsData(String font) {
|
||||||
|
this.font = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFont() {
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFont(String font) {
|
||||||
|
this.font = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FontsFingerprint> getPartOf() {
|
||||||
|
return partOf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPartOf(Set<FontsFingerprint> partOf) {
|
||||||
|
this.partOf = partOf;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
public interface FontsDataRepo extends CrudRepository<FontsData, String> {
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class FontsFingerprint {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy= GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToMany(cascade = { CascadeType.ALL })
|
||||||
|
@JoinTable(
|
||||||
|
name="fonts_font",
|
||||||
|
joinColumns = { @JoinColumn(name="fonts_id")},
|
||||||
|
inverseJoinColumns = { @JoinColumn(name="font_id")}
|
||||||
|
)
|
||||||
|
private Set<FontsData> installedFonts;
|
||||||
|
|
||||||
|
FontsFingerprint(){
|
||||||
|
|
||||||
|
}
|
||||||
|
public FontsFingerprint(Set<FontsData> installedFonts) {
|
||||||
|
this.installedFonts = installedFonts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FontsData> getInstalledFonts() {
|
||||||
|
return installedFonts;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface FontsFingerprintRepo extends CrudRepository<FontsFingerprint, Long> {
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class HeaderFingerprint {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy= GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
private String osType;
|
||||||
|
private String osVersion;
|
||||||
|
private String osSubVersion;
|
||||||
|
private String device;
|
||||||
|
|
||||||
|
private String useragentFamily;
|
||||||
|
private String useragentVerison;
|
||||||
|
private String useragentSubVersion;
|
||||||
|
|
||||||
|
private Set<String> accepts;
|
||||||
|
private Set<String> encoding;
|
||||||
|
private Set<String> languages;
|
||||||
|
|
||||||
|
HeaderFingerprint(){
|
||||||
|
|
||||||
|
}
|
||||||
|
public HeaderFingerprint(String osType, String osVersion, String osSubVersion, String device, String useragentFamily, String useragentVerison, String useragentSubVersion, Set<String> accepts, Set<String> encoding, Set<String> languages) {
|
||||||
|
this.osType = osType;
|
||||||
|
this.osVersion = osVersion;
|
||||||
|
this.osSubVersion = osSubVersion;
|
||||||
|
this.device = device;
|
||||||
|
this.useragentFamily = useragentFamily;
|
||||||
|
this.useragentVerison = useragentVerison;
|
||||||
|
this.useragentSubVersion = useragentSubVersion;
|
||||||
|
this.accepts = accepts;
|
||||||
|
this.encoding = encoding;
|
||||||
|
this.languages = languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOsType() {
|
||||||
|
return osType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOsVersion() {
|
||||||
|
return osVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOsSubVersion() {
|
||||||
|
return osSubVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUseragentFamily() {
|
||||||
|
return useragentFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUseragentVerison() {
|
||||||
|
return useragentVerison;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUseragentSubVersion() {
|
||||||
|
return useragentSubVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getAccepts() {
|
||||||
|
return accepts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getEncoding() {
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getLanguages() {
|
||||||
|
return languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface HeaderFingerprintRepo extends CrudRepository<HeaderFingerprint, Long> {
|
||||||
|
|
||||||
|
Set<HeaderFingerprint> findByOsTypeIs(String value);
|
||||||
|
Set<HeaderFingerprint> findByOsTypeIsAndOsVersionIs(String value, String value2);
|
||||||
|
Set<HeaderFingerprint> findByOsTypeIsAndOsVersionIsAndOsSubVersionIs(String value, String value2, String value3);
|
||||||
|
Set<HeaderFingerprint> findByDeviceIs(String value);
|
||||||
|
Set<HeaderFingerprint> findByUseragentFamilyIs(String value);
|
||||||
|
Set<HeaderFingerprint> findByUseragentFamilyIsAndUseragentVerisonIs(String value, String value2);
|
||||||
|
Set<HeaderFingerprint> findByUseragentFamilyIsAndUseragentVerisonIsAndUseragentSubVersionIs(String value, String value2, String value3);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class ScreenSizeFinerPrint {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy= GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
|
||||||
|
ScreenSizeFinerPrint(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScreenSizeFinerPrint(int screenX, int screenY){
|
||||||
|
this.width = screenX;
|
||||||
|
this.height = screenY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(int width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(int height) {
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface ScreenSizeFinerPrintRepo extends CrudRepository<ScreenSizeFinerPrint, Long> {
|
||||||
|
Set<ScreenSizeFinerPrint> findAllByWidthEquals(int width);
|
||||||
|
Set<ScreenSizeFinerPrint> findAllByHeightEquals(int height);
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class UserSession {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy= GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String sessionID;
|
||||||
|
|
||||||
|
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "screenSize_id", referencedColumnName = "id")
|
||||||
|
private ScreenSizeFinerPrint screenSizeFinerPrint;
|
||||||
|
|
||||||
|
|
||||||
|
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "fonts_id", referencedColumnName = "id")
|
||||||
|
private FontsFingerprint fontsFingerprint;
|
||||||
|
|
||||||
|
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "header_id", referencedColumnName = "id")
|
||||||
|
private HeaderFingerprint headerFingerprint;
|
||||||
|
|
||||||
|
UserSession(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserSession(String sessionID){
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionID() {
|
||||||
|
return sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSessionID(String sessionID) {
|
||||||
|
this.sessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScreenSizeFinerPrint getScreenSizeFinerPrint() {
|
||||||
|
return screenSizeFinerPrint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScreenSizeFinerPrint(ScreenSizeFinerPrint screenSizeFinerPrint) {
|
||||||
|
this.screenSizeFinerPrint = screenSizeFinerPrint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontsFingerprint getFontsFingerprint() {
|
||||||
|
return fontsFingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFontsFingerprint(FontsFingerprint fontsFingerprint) {
|
||||||
|
this.fontsFingerprint = fontsFingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HeaderFingerprint getHeaderFingerprint() {
|
||||||
|
return headerFingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeaderFingerprint(HeaderFingerprint headerFingerprint) {
|
||||||
|
this.headerFingerprint = headerFingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.data;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface UserSessionRepo extends CrudRepository<UserSession, Long> {
|
||||||
|
Optional<UserSession> findBySessionID(String sessionID);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.dto;
|
||||||
|
|
||||||
|
import de.unileipzig.datenschutz.paper10.demo.data.FontsData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class FontList {
|
||||||
|
|
||||||
|
private List<FontStatus> fonts = new ArrayList<FontStatus>();
|
||||||
|
|
||||||
|
public List<FontStatus> getFonts() {
|
||||||
|
return fonts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFonts(List<FontStatus> fonts) {
|
||||||
|
this.fonts = fonts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontStatus getFontStatus(int pos){
|
||||||
|
return fonts.get(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFontStatus(FontStatus fontStatus){
|
||||||
|
fonts.add(fontStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FontsData> getInstalledFonts(){
|
||||||
|
return fonts.stream().filter(FontStatus::isActive).map(fontStatus -> new FontsData(fontStatus.getFontName())).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.dto;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class FontListDto {
|
||||||
|
|
||||||
|
ArrayList<ArrayList<String>> fonts;
|
||||||
|
|
||||||
|
public ArrayList<ArrayList<String>> getFonts() {
|
||||||
|
return fonts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFonts(ArrayList<ArrayList<String>> fonts) {
|
||||||
|
this.fonts = fonts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FontList parseToFontList(Object object){
|
||||||
|
FontList fontList = new FontList();
|
||||||
|
|
||||||
|
ArrayList e1 = (ArrayList) object;
|
||||||
|
|
||||||
|
for (Object object2 : e1){
|
||||||
|
ArrayList e2 = (ArrayList) object2;
|
||||||
|
|
||||||
|
fontList.addFontStatus(new FontStatus(
|
||||||
|
(String) e2.get(0),
|
||||||
|
(Integer) e2.get(1),
|
||||||
|
(Integer) e2.get(2),
|
||||||
|
(Boolean) e2.get(3)
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return fontList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.dto;
|
||||||
|
public class FontStatus {
|
||||||
|
private String fontName;
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
private boolean isActive;
|
||||||
|
|
||||||
|
public FontStatus(){
|
||||||
|
|
||||||
|
}
|
||||||
|
public FontStatus(String fontName, int width, int height, boolean isActive) {
|
||||||
|
this.fontName = fontName;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.isActive = isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFontName() {
|
||||||
|
return fontName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFontName(String fontName) {
|
||||||
|
this.fontName = fontName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(int width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(int height) {
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(boolean active) {
|
||||||
|
isActive = active;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.dto;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ScreenSize {
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
|
||||||
|
public ScreenSize(int width, int height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(int width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(int height) {
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
ScreenSize that = (ScreenSize) o;
|
||||||
|
return width == that.width && height == that.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(width, height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package de.unileipzig.datenschutz.paper10.demo.dto;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ScreenSizeData {
|
||||||
|
private ScreenSize screenSize;
|
||||||
|
public ScreenSize getScreenSize() {
|
||||||
|
return screenSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScreenSize(ScreenSize screenSize) {
|
||||||
|
this.screenSize = screenSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
ScreenSizeData that = (ScreenSizeData) o;
|
||||||
|
return Objects.equals(screenSize, that.screenSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(screenSize);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,9 @@
|
||||||
|
spring.thymeleaf.cache=false
|
||||||
|
|
||||||
|
spring.session.store-type=jdbc
|
||||||
|
|
||||||
|
spring.datasource.url=jdbc:h2:mem:testdb
|
||||||
|
spring.datasource.driverClassName=org.h2.Driver
|
||||||
|
spring.datasource.username=sa
|
||||||
|
spring.datasource.password=password
|
||||||
|
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
10
src/main/resources/static/index.html
Normal file
10
src/main/resources/static/index.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Getting Started: Serving Web Content</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>Get your greeting <a href="/">here</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
150
src/main/resources/static/js/fontTracker.js
Normal file
150
src/main/resources/static/js/fontTracker.js
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
// Form https://gist.github.com/tingletech/1582068
|
||||||
|
|
||||||
|
var Detector = function(){
|
||||||
|
var h = document.getElementsByTagName("BODY")[0];
|
||||||
|
var d = document.createElement("DIV");
|
||||||
|
var s = document.createElement("SPAN");
|
||||||
|
d.appendChild(s);
|
||||||
|
d.style.fontFamily = "serif"; //font for the parent element DIV.
|
||||||
|
s.style.fontFamily = "serif"; //have to use serif coz in FF3.0, it doesn't fall back to font of parent element.
|
||||||
|
s.style.fontSize = "72px"; //we test using 72px font size, we may use any size. I guess larger the better.
|
||||||
|
s.innerHTML = "mmmmmmmmmml"; //we use m or w because these two characters take up the maximum width. And we use a L so that the same matching fonts can get separated
|
||||||
|
h.appendChild(d);
|
||||||
|
var defaultWidth = s.offsetWidth; //now we have the defaultWidth
|
||||||
|
var defaultHeight = s.offsetHeight; //and the defaultHeight, we compare other fonts with these.
|
||||||
|
h.removeChild(d);
|
||||||
|
/* test
|
||||||
|
* params:
|
||||||
|
* font - name of the font you wish to detect
|
||||||
|
* return:
|
||||||
|
* f[0] - Input font name.
|
||||||
|
* f[1] - Computed width.
|
||||||
|
* f[2] - Computed height.
|
||||||
|
* f[3] - Detected? (true/false).
|
||||||
|
*/
|
||||||
|
function debug(font) {
|
||||||
|
h.appendChild(d);
|
||||||
|
var f = [];
|
||||||
|
f[0] = s.style.fontFamily = font; // Name of the font
|
||||||
|
f[1] = s.offsetWidth; // Width
|
||||||
|
f[2] = s.offsetHeight; // Height
|
||||||
|
h.removeChild(d);
|
||||||
|
font = font.toLowerCase();
|
||||||
|
if (font == "serif") {
|
||||||
|
f[3] = true; // to set arial and sans-serif true
|
||||||
|
} else {
|
||||||
|
f[3] = (f[1] != defaultWidth || f[2] != defaultHeight); // Detected?
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
function test(font){
|
||||||
|
f = debug(font);
|
||||||
|
return f[3];
|
||||||
|
}
|
||||||
|
this.detailedTest = debug;
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
var fonts = [];
|
||||||
|
/**
|
||||||
|
* other stuff
|
||||||
|
*/
|
||||||
|
function init() {
|
||||||
|
fonts.push("cursive");
|
||||||
|
fonts.push("Helvetica");
|
||||||
|
fonts.push("monospace");
|
||||||
|
fonts.push("serif");
|
||||||
|
fonts.push("sans-serif");
|
||||||
|
fonts.push("fantasy");
|
||||||
|
fonts.push("default");
|
||||||
|
fonts.push("Arial");
|
||||||
|
fonts.push("Arial Black");
|
||||||
|
fonts.push("Arial Narrow");
|
||||||
|
fonts.push("Arial Rounded MT Bold");
|
||||||
|
fonts.push("Bookman Old Style");
|
||||||
|
fonts.push("Bradley Hand ITC");
|
||||||
|
fonts.push("Century");
|
||||||
|
fonts.push("Century Gothic");
|
||||||
|
fonts.push("Gotham");
|
||||||
|
fonts.push("Comic Sans MS");
|
||||||
|
fonts.push("Courier");
|
||||||
|
fonts.push("Courier New");
|
||||||
|
fonts.push("Georgia");
|
||||||
|
fonts.push("Roboto");
|
||||||
|
fonts.push("Lato");
|
||||||
|
fonts.push("Montserrat");
|
||||||
|
fonts.push("Gentium");
|
||||||
|
fonts.push("Source Sans Pro");
|
||||||
|
fonts.push("Bookman");
|
||||||
|
fonts.push("Brush Script");
|
||||||
|
fonts.push("PT Sans");
|
||||||
|
fonts.push("Raleway");
|
||||||
|
fonts.push("Didot");
|
||||||
|
fonts.push("Franklin Gothic");
|
||||||
|
fonts.push("Open Sans");
|
||||||
|
fonts.push("Univers");
|
||||||
|
fonts.push("Copperplate");
|
||||||
|
fonts.push("Impact");
|
||||||
|
fonts.push("Futura");
|
||||||
|
fonts.push("Optima");
|
||||||
|
fonts.push("Rockwell");
|
||||||
|
fonts.push("Gill Sans");
|
||||||
|
fonts.push("Zapfino");
|
||||||
|
fonts.push("Myriad");
|
||||||
|
fonts.push("King");
|
||||||
|
fonts.push("Trajan");
|
||||||
|
fonts.push("Lucida Console");
|
||||||
|
fonts.push("Poppins");
|
||||||
|
fonts.push("Lalit");
|
||||||
|
fonts.push("Oswald");
|
||||||
|
fonts.push("Ubuntu");
|
||||||
|
fonts.push("Modena");
|
||||||
|
fonts.push("Nunito");
|
||||||
|
fonts.push("Monotype Corsiva");
|
||||||
|
fonts.push("Papyrus");
|
||||||
|
fonts.push("Tahoma");
|
||||||
|
fonts.push("Garamond");
|
||||||
|
fonts.push("TeX");
|
||||||
|
fonts.push("Times");
|
||||||
|
fonts.push("Palatino");
|
||||||
|
fonts.push("Baskerville");
|
||||||
|
fonts.push("Times New Roman");
|
||||||
|
fonts.push("Trebuchet MS");
|
||||||
|
fonts.push("Verdana");
|
||||||
|
fonts.push("Verona");
|
||||||
|
d = new Detector();
|
||||||
|
// compute height and width for all fonts
|
||||||
|
for (i=0; i<fonts.length; i++) {
|
||||||
|
fonts.push(d.detailedTest(fonts.shift()));
|
||||||
|
}
|
||||||
|
sortResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortResults() {
|
||||||
|
for (i=0; i<fonts.length-1; i++) {
|
||||||
|
for (j=i; j<fonts.length; j++) {
|
||||||
|
if(fonts[i][1] < fonts[j][1]) {
|
||||||
|
t = fonts[i];
|
||||||
|
fonts[i] = fonts[j];
|
||||||
|
fonts[j] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var fontTracker = function() {
|
||||||
|
|
||||||
|
init();
|
||||||
|
console.log(fonts);
|
||||||
|
|
||||||
|
// Sende die erfassten Daten an den Spring REST-Endpunkt
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "/fonts", true);
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
var data = JSON.stringify(fonts);
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
xhr.send(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', fontTracker, false);
|
23
src/main/resources/static/js/tracker.js
Normal file
23
src/main/resources/static/js/tracker.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// JavaScript-Code
|
||||||
|
var trackScreen = function() {
|
||||||
|
// Erfasse die Bildschirmgröße
|
||||||
|
var screenSize = {
|
||||||
|
width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
|
||||||
|
height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sende die erfassten Daten an den Spring REST-Endpunkt
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "/screensize", true);
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
var data = JSON.stringify({
|
||||||
|
screenSize: screenSize
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
xhr.send(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', trackScreen, false);
|
31
src/main/resources/static/syle/style.css
Normal file
31
src/main/resources/static/syle/style.css
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background-color: #D6EEEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
td:nth-child(1){
|
||||||
|
width: 44%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td:nth-child(2){
|
||||||
|
width: 44%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td:nth-child(3){
|
||||||
|
width: 8%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
}
|
||||||
|
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid black;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
105
src/main/resources/templates/main.html
Normal file
105
src/main/resources/templates/main.html
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<title>Getting Started: Serving Web Content</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<link rel="stylesheet" href="syle/style.css">
|
||||||
|
<script src="js/fontTracker.js"></script>
|
||||||
|
<script src="js/tracker.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Hi there!</h2>
|
||||||
|
<p>Deine Session ID: <span th:text="${session_id}"></span></p>
|
||||||
|
<br>
|
||||||
|
<a href="/"><h3>RELOAD!</h3></a>
|
||||||
|
<br>
|
||||||
|
<h3>Deine Daten:</h3>
|
||||||
|
<table>
|
||||||
|
<caption>Application</caption>
|
||||||
|
<tr>
|
||||||
|
<th>Werte name</th>
|
||||||
|
<th>Wert ausprägung</th>
|
||||||
|
<th>Anzahl an Personen mit gleichem wert</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Session ID:</td>
|
||||||
|
<td th:text="${session_id}"></td>
|
||||||
|
<td>0</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Screen Size:</h3>
|
||||||
|
<table th:if="${show_screen_size}">
|
||||||
|
<tr>
|
||||||
|
<td>width:</td>
|
||||||
|
<td th:text="${screenSizeFinerPrint_width}"></td>
|
||||||
|
<td th:text="${screenSizeFinerPrint_width_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>height:</td>
|
||||||
|
<td th:text="${screenSizeFinerPrint_height}"></td>
|
||||||
|
<td th:text="${screenSizeFinerPrint_height_count}"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Usable Fonts:</h3>
|
||||||
|
<table th:if="${show_fonts}">
|
||||||
|
<tr th:each="font : ${fontsFingerprint_installedFonts}">
|
||||||
|
<td>Font Name</td>
|
||||||
|
<td th:text="${font.name}"></td>
|
||||||
|
<td th:text="${font.count}"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Header:</h3>
|
||||||
|
<table th:if="${show_header}">
|
||||||
|
<tr>
|
||||||
|
<td>OS</td>
|
||||||
|
<td th:text="${headerFingerprint_os_type}"></td>
|
||||||
|
<td th:text="${headerFingerprint_os_type_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OS Version</td>
|
||||||
|
<td th:text="${headerFingerprint_os_version}"></td>
|
||||||
|
<td th:text="${headerFingerprint_os_version_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OS SubVersion</td>
|
||||||
|
<td th:text="${headerFingerprint_os_sub_version}"></td>
|
||||||
|
<td th:text="${headerFingerprint_os_sub_version_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Gerät</td>
|
||||||
|
<td th:text="${headerFingerprint_device}"></td>
|
||||||
|
<td th:text="${headerFingerprint_device_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UserAgent</td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family}"></td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UserAgent Version</td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_version}"></td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_version_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UserAgent SubVersion</td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_sub_version}"></td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_sub_version_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>accepts</td>
|
||||||
|
<td th:text="${headerFingerprint_accepts}"></td>
|
||||||
|
<td>-1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>encoding</td>
|
||||||
|
<td th:text="${headerFingerprint_encoding}"></td>
|
||||||
|
<td>-1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>accept</td>
|
||||||
|
<td th:text="${headerFingerprint_languages}"></td>
|
||||||
|
<td>-1</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
101
src/main/resources/templates/overwiev.html
Normal file
101
src/main/resources/templates/overwiev.html
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<title>Getting Started: Serving Web Content</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<link rel="stylesheet" href="syle/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Übersicht</h2>
|
||||||
|
<a href="/"><h3>RELOAD!</h3></a>
|
||||||
|
<br>
|
||||||
|
<h3>Generelle Daten:</h3>
|
||||||
|
<table>
|
||||||
|
<caption>Application</caption>
|
||||||
|
<tr>
|
||||||
|
<th>Werte name</th>
|
||||||
|
<th>Wert ausprägung</th>
|
||||||
|
<th>Anzahl an Personen mit gleichem wert</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Session IDs:</td>
|
||||||
|
<td> - </td>
|
||||||
|
<td th:text="${session_ids}"> - </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Screen Size:</h3>
|
||||||
|
<table th:if="${show_screen_size}">
|
||||||
|
<tr th:each=" width : ${screenSizeFinerPrint_widths}">
|
||||||
|
<td>width:</td>
|
||||||
|
<td th:text="${width}"></td>
|
||||||
|
<td th:text="${width_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td th:each=" height : ${screenSizeFinerPrint_height}">height:</td>
|
||||||
|
<td th:text="${height}"></td>
|
||||||
|
<td th:text="${height_count}"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Usable Fonts:</h3>
|
||||||
|
<table th:if="${show_fonts}">
|
||||||
|
<tr th:each="font : ${fontsFingerprint_installedFonts}">
|
||||||
|
<td>Font Name</td>
|
||||||
|
<td th:text="${font.name}"></td>
|
||||||
|
<td th:text="${font.count}"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h3>Header:</h3>
|
||||||
|
<table th:if="${show_header}">
|
||||||
|
<tr>
|
||||||
|
<td>OS</td>
|
||||||
|
<td th:text="${headerFingerprint_os_type}"></td>
|
||||||
|
<td th:text="${headerFingerprint_os_type_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OS Version</td>
|
||||||
|
<td th:text="${headerFingerprint_os_version}"></td>
|
||||||
|
<td th:text="${headerFingerprint_os_version_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OS SubVersion</td>
|
||||||
|
<td th:text="${headerFingerprint_os_sub_version}"></td>
|
||||||
|
<td th:text="${headerFingerprint_os_sub_version_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Gerät</td>
|
||||||
|
<td th:text="${headerFingerprint_device}"></td>
|
||||||
|
<td th:text="${headerFingerprint_device_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UserAgent</td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family}"></td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UserAgent Version</td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_version}"></td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_version_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UserAgent SubVersion</td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_sub_version}"></td>
|
||||||
|
<td th:text="${headerFingerprint_useragent_family_sub_version_count}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>accepts</td>
|
||||||
|
<td th:text="${headerFingerprint_accepts}"></td>
|
||||||
|
<td>-1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>encoding</td>
|
||||||
|
<td th:text="${headerFingerprint_encoding}"></td>
|
||||||
|
<td>-1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>accept</td>
|
||||||
|
<td th:text="${headerFingerprint_languages}"></td>
|
||||||
|
<td>-1</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue