[DEV] work onn edge and application right ==> refacto th generation of the right
This commit is contained in:
parent
dd936c2e94
commit
10cd17e594
@ -27,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>kangaroo-and-rabbit</groupId>
|
||||
<artifactId>archidata</artifactId>
|
||||
<version>0.3.2</version>
|
||||
<version>0.3.5</version>
|
||||
</dependency>
|
||||
<!-- testing -->
|
||||
<dependency>
|
||||
|
@ -12,8 +12,11 @@ import org.kar.karso.api.UserResource;
|
||||
import org.kar.karso.filter.KarsoAuthenticationFilter;
|
||||
import org.kar.karso.model.Application;
|
||||
import org.kar.karso.model.ApplicationToken;
|
||||
import org.kar.karso.model.Right;
|
||||
import org.kar.karso.model.RightDescription;
|
||||
import org.kar.karso.model.Settings;
|
||||
import org.kar.karso.model.UserAuth;
|
||||
import org.kar.karso.util.ConfigVariable;
|
||||
//import org.kar.archidata.model.Migration;
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.catcher.ExceptionCatcher;
|
||||
@ -38,10 +41,11 @@ public class WebLauncher {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
ConfigBaseVariable.bdDatabase = "karso";
|
||||
ConfigBaseVariable.bdDatabase =
|
||||
"karso";
|
||||
|
||||
try {
|
||||
JWTWrapper.initLocalToken();
|
||||
JWTWrapper.initLocalToken(ConfigVariable.getUUIDKeyRoot());
|
||||
} catch (Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
@ -57,17 +61,33 @@ public class WebLauncher {
|
||||
out += SqlWrapper.createTable(UserAuth.class);
|
||||
out += SqlWrapper.createTable(Application.class);
|
||||
out += SqlWrapper.createTable(ApplicationToken.class);
|
||||
out += SqlWrapper.createTable(RightDescription.class);
|
||||
out += SqlWrapper.createTable(Right.class);
|
||||
// default admin: "karadmin" password: "adminA@666"
|
||||
out += """
|
||||
INSERT INTO `user` (`login`, `password`, `email`, `admin`) VALUES
|
||||
('karadmin', '0ddcac5ede3f1300a1ce5948ab15112f2810130531d578ab8bc4dc131652d7cf7a3ff6e827eb957bff43bc2c65a6a1d46722e5b3a2343ac3176a33ea7250080b',
|
||||
INSERT INTO `application` (`id`, `name`, `description`, `redirect`, `redirectDev`, `notification`, `ttl`) VALUES
|
||||
('0', 'karso', 'Root SSO interface', 'http://atria-soft/karso', '', '', '666');
|
||||
""";
|
||||
out += """
|
||||
INSERT INTO `user` (`id`, `login`, `password`, `email`, `admin`) VALUES
|
||||
('0', 'karadmin', '0ddcac5ede3f1300a1ce5948ab15112f2810130531d578ab8bc4dc131652d7cf7a3ff6e827eb957bff43bc2c65a6a1d46722e5b3a2343ac3176a33ea7250080b',
|
||||
'admin@admin.ZZZ', 1);
|
||||
""";
|
||||
out += """
|
||||
INSERT INTO `settings` (`key`, `right`, `type`, `value`) VALUES
|
||||
('SIGN_UP_ENABLE', 'rwr-r-', 'BOOLEAN', 'false'),
|
||||
('SIGN_IN_ENABLE', 'rwr-r-', 'BOOLEAN', 'true'),
|
||||
('SIGN_UP_FILTER', 'rw----', 'STRING', '.*'),
|
||||
('EMAIL_VALIDATION_REQUIRED', 'rwr-r-', 'BOOLEAN', 'false');
|
||||
""";
|
||||
out += """
|
||||
INSERT INTO `rightDescription` (`id`, `applicationId`, `key`, `title`, `description`, `type`) VALUES
|
||||
(0, 0, 'ADMIN', 'Administrator', 'Full administrator Right', 'BOOLEAN');
|
||||
""";
|
||||
out += """
|
||||
INSERT INTO `right` (`applicationId`, `userId`, `rightDescriptionId`, `value`) VALUES
|
||||
(0, 0, 0, 'true');
|
||||
""";
|
||||
//out += SqlWrapper.createTable(Migration.class);
|
||||
System.out.println(out);
|
||||
|
||||
@ -123,7 +143,6 @@ public class WebLauncher {
|
||||
try {
|
||||
server.start();
|
||||
System.out.println("Jersey app started at " + getBaseURI());
|
||||
System.out.println("Press CTRL^C to exit..");
|
||||
Thread.currentThread().join();
|
||||
} catch (Exception e) {
|
||||
System.out.println("There was an error while starting Grizzly HTTP server.");
|
||||
|
22
back/src/org/kar/karso/WebLauncherEdgeLocal.java
Executable file
22
back/src/org/kar/karso/WebLauncherEdgeLocal.java
Executable file
@ -0,0 +1,22 @@
|
||||
|
||||
package org.kar.karso;
|
||||
|
||||
import org.kar.archidata.util.ConfigBaseVariable;
|
||||
import org.kar.karso.util.ConfigVariable;
|
||||
|
||||
public class WebLauncherEdgeLocal {
|
||||
private WebLauncherEdgeLocal() {}
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
if (true) {
|
||||
// for local test:
|
||||
ConfigBaseVariable.apiAdress = "http://0.0.0.0:15080/karso/api/";
|
||||
ConfigBaseVariable.dbPort = "3306";
|
||||
ConfigVariable.edge = "true";
|
||||
//ConfigBaseVariable.dbType = "sqlite";
|
||||
//ConfigBaseVariable.dbHost = "./bdd_base.sqlite";
|
||||
|
||||
}
|
||||
WebLauncher.main(args);
|
||||
}
|
||||
}
|
@ -1,13 +1,17 @@
|
||||
package org.kar.karso.api;
|
||||
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.WhereCondition;
|
||||
import org.kar.archidata.filter.GenericContext;
|
||||
import org.kar.karso.model.*;
|
||||
import org.kar.archidata.util.JWTWrapper;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import org.kar.archidata.exception.InputException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
@ -22,28 +26,67 @@ public class ApplicationResource {
|
||||
|
||||
public ApplicationResource() {
|
||||
}
|
||||
|
||||
public List<Long> getUserListOfApplication(Long userId) {
|
||||
List<Long> out = new ArrayList<>();
|
||||
List<UserLinkApplication> links = null;
|
||||
try {
|
||||
links = SqlWrapper.getsWhere(UserLinkApplication.class,
|
||||
List.of(
|
||||
new WhereCondition("user_id", "=", userId),
|
||||
new WhereCondition("deleted", "=", 0)
|
||||
), false);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "SERVER Internal error";
|
||||
System.out.println(" result: " + result);
|
||||
return out;
|
||||
}
|
||||
for (UserLinkApplication app : links) {
|
||||
out.add(app.application_id);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@GET
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
public List<Application> getApplications() throws Exception {
|
||||
public List<Application> getApplications(@Context SecurityContext sc) throws Exception {
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
System.out.println("getApplications");
|
||||
return SqlWrapper.gets(Application.class, false);
|
||||
// TODO filter with the list of element available in his authorizations ...
|
||||
List<Application> tmp = SqlWrapper.gets(Application.class, false);
|
||||
List<Long> regular = this.getUserListOfApplication(gc.userByToken.id);
|
||||
List<Application> out = new ArrayList<>();
|
||||
for (Application app : tmp) {
|
||||
if (regular.indexOf(app.id) != -1) {
|
||||
out.add(app);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("small")
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
public List<ApplicationSmall> getApplicationsSmall() throws Exception {
|
||||
public List<ApplicationSmall> getApplicationsSmall(@Context SecurityContext sc) throws Exception {
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
System.out.println("getApplications");
|
||||
return SqlWrapper.gets(ApplicationSmall.class, false);
|
||||
List<Application> tmp = SqlWrapper.gets(Application.class, false);
|
||||
List<Long> regular = this.getUserListOfApplication(gc.userByToken.id);
|
||||
List<ApplicationSmall> out = new ArrayList<>();
|
||||
for (Application app : tmp) {
|
||||
if (regular.indexOf(app.id) != -1) {
|
||||
out.add(new ApplicationSmall(app.name, app.description, app.redirect));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("get_token")
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
public Response getClientToken(@Context SecurityContext sc, @QueryParam("application") String application) {
|
||||
public Response getClientToken(@Context SecurityContext sc, @QueryParam("application") String application) throws Exception {
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
System.out.println("== USER ? " + gc.user);
|
||||
System.out.println("== USER ? " + gc.userByToken);
|
||||
|
||||
if (application == null) {
|
||||
String result = "Input error missing parameter: 'application'";
|
||||
@ -60,7 +103,7 @@ public class ApplicationResource {
|
||||
|
||||
Application appl = null;
|
||||
try {
|
||||
appl = SqlWrapper.getWhere(Application.class, "name", "=", applicationName);
|
||||
appl = SqlWrapper.getWhere(Application.class, List.of(new WhereCondition("name", "=", applicationName)), false);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
@ -72,11 +115,64 @@ public class ApplicationResource {
|
||||
if (appl == null) {
|
||||
String result = "Authentiocate-wrong email/login '" + applicationName + "')";
|
||||
System.out.println(" result: " + result);
|
||||
return Response.status(404).entity(result).build();
|
||||
return Response.status(401).entity(result).build();
|
||||
}
|
||||
// Manage application right here...
|
||||
|
||||
String ret = JWTWrapper.generateJWToken(gc.user.id, gc.user.login, "KarAuth", applicationName, appl.ttl);
|
||||
if (false) {
|
||||
// the pplication id is not streamed in the application liny in the where elements
|
||||
// get the local user:
|
||||
UserAuth localUser = null;
|
||||
try {
|
||||
localUser = SqlWrapper.get(UserAuth.class, gc.userByToken.id);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "SERVER Internal error";
|
||||
System.out.println(" result: " + result);
|
||||
return Response.status(500).entity(result).build();
|
||||
}
|
||||
if (localUser == null) {
|
||||
String result = "Authenticate-wrong results '" + applicationName + "')";
|
||||
System.out.println(" result: " + result);
|
||||
return Response.status(401).entity(result).build();
|
||||
}
|
||||
System.out.println("Get application list: " + localUser.applications);
|
||||
if (localUser.applications == null || localUser.applications.indexOf((Long)gc.userByToken.id) == -1) {
|
||||
String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'";
|
||||
System.out.println(" result: " + result);
|
||||
return Response.status(401).entity(result).build();
|
||||
}
|
||||
} else {
|
||||
UserLinkApplication links = null;
|
||||
try {
|
||||
links = SqlWrapper.getWhere(UserLinkApplication.class,
|
||||
List.of(
|
||||
new WhereCondition("user_id", "=", gc.userByToken.id),
|
||||
new WhereCondition("deleted", "=", 0),
|
||||
new WhereCondition("application_id", "=", appl.id)
|
||||
), false);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
String result = "SERVER Internal error";
|
||||
System.out.println(" result: " + result);
|
||||
return Response.status(500).entity(result).build();
|
||||
}
|
||||
if (links == null) {
|
||||
String result = "Authenticate impossible ==> application not accessible '" + applicationName + "'";
|
||||
System.out.println(" result: " + result);
|
||||
return Response.status(401).entity(result).build();
|
||||
}
|
||||
}
|
||||
// Get the USER Right
|
||||
Map<String, Object> applicationRight = RightResource.getUserRight(gc.userByToken.id, appl.id);
|
||||
if (!applicationRight.containsKey("USER")) {
|
||||
// If the USER is not override, the system add by default USER
|
||||
applicationRight.put("USER", true);
|
||||
}
|
||||
Map<String, Object> outRight = new HashMap<>();
|
||||
// we set the right in the under map to manage multiple application group right. and in some application user can see other user or all user of the application
|
||||
outRight.put(applicationName, applicationRight);
|
||||
String ret = JWTWrapper.generateJWToken(gc.userByToken.id, gc.userByToken.name, "KarAuth", applicationName, outRight, appl.ttl);
|
||||
//System.out.println(" ==> generate token: " + ret);
|
||||
String returnAdress = appl.redirect;
|
||||
if (isDev) {
|
||||
@ -93,7 +189,7 @@ public class ApplicationResource {
|
||||
System.out.println("Get log_out()");
|
||||
System.out.println("=====================================");
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
System.out.println("== USER ? " + gc.user);
|
||||
System.out.println("== USER ? " + gc.userByToken);
|
||||
|
||||
if (application == null) {
|
||||
String result = "Input error missing parameter: 'application'";
|
||||
|
109
back/src/org/kar/karso/api/RightResource.java
Normal file
109
back/src/org/kar/karso/api/RightResource.java
Normal file
@ -0,0 +1,109 @@
|
||||
package org.kar.karso.api;
|
||||
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.WhereCondition;
|
||||
import org.kar.karso.model.Right;
|
||||
import org.kar.karso.model.RightDescription;
|
||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Path("/right")
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
public class RightResource {
|
||||
|
||||
|
||||
public static Object transform(String type, String value) {
|
||||
if ("BOOLEAN".equals(type)) {
|
||||
return Boolean.valueOf(value);
|
||||
} else if ("STRING".equals(type)) {
|
||||
return value;
|
||||
} else if ("LONG".equals(type)) {
|
||||
return Long.valueOf(value);
|
||||
} else if ("NUMBER".equals(type)) {
|
||||
return Double.valueOf(value);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Object> getUserRight(long userId, long applicationId) throws Exception {
|
||||
Map<String, Object> out = new HashMap<>();
|
||||
List<RightDescription> rightsDescriptions = SqlWrapper.getsWhere(RightDescription.class,
|
||||
List.of(
|
||||
new WhereCondition("applicationId", "=", applicationId),
|
||||
new WhereCondition("deleted", "=", 0)
|
||||
));
|
||||
System.out.println("Get some descriptions: " + rightsDescriptions.size() + " applicationId=" + applicationId);
|
||||
if (rightsDescriptions != null && rightsDescriptions.size() != 0) {
|
||||
List<Right> rights = SqlWrapper.getsWhere(Right.class,
|
||||
List.of(
|
||||
new WhereCondition("applicationId", "=", applicationId),
|
||||
new WhereCondition("userId", "=", userId),
|
||||
new WhereCondition("deleted", "=", 0)
|
||||
));
|
||||
System.out.println("Get some user right: " + rights.size() + " userID=" + userId);
|
||||
if (rights != null && rights.size() != 0) {
|
||||
for (Right right: rights) {
|
||||
RightDescription description = rightsDescriptions.stream()
|
||||
.filter(elem -> right.rightDescriptionId == elem.id)
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
if (description != null) {
|
||||
out.put(description.key, transform(description.type, right.value));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println("The User have no specific right...");
|
||||
}
|
||||
} else {
|
||||
// the application does not manage right with Karso (normal use-case)
|
||||
System.out.println("Does not manage Karso right...");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public static Right getWithId(@PathParam("id") Long id) throws Exception {
|
||||
return SqlWrapper.get(Right.class, id);
|
||||
}
|
||||
|
||||
@GET
|
||||
@RolesAllowed("ADMIN")
|
||||
public List<Right> get() throws Exception {
|
||||
return SqlWrapper.gets(Right.class, false);
|
||||
}
|
||||
|
||||
@POST
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Right post(String jsonRequest) throws Exception {
|
||||
return SqlWrapper.insertWithJson(Right.class, jsonRequest);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Right put(@PathParam("id") Long id, String jsonRequest) throws Exception {
|
||||
SqlWrapper.update(Right.class, id, jsonRequest);
|
||||
return SqlWrapper.get(Right.class, id);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Response delete(@PathParam("id") Long id) throws Exception {
|
||||
SqlWrapper.setDelete(Right.class, id);
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public class SystemConfigResource {
|
||||
JsonNode value = root.findPath("value");
|
||||
|
||||
res.value = value.asText();
|
||||
System.out.println(" update valu : " + res.value);
|
||||
System.out.println("Update value : " + res.value);
|
||||
SqlWrapper.update(res, res.id, List.of("value"));
|
||||
return Response.status(201).entity("{ \"value\":\"" + res.value + "\"}").build();
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.kar.karso.api;
|
||||
|
||||
import org.kar.archidata.model.GetToken;
|
||||
import org.kar.archidata.model.User;
|
||||
import org.kar.archidata.SqlWrapper;
|
||||
import org.kar.archidata.WhereCondition;
|
||||
import org.kar.archidata.annotation.security.PermitAll;
|
||||
@ -12,6 +11,9 @@ import org.kar.archidata.exception.SystemException;
|
||||
import org.kar.archidata.filter.GenericContext;
|
||||
import org.kar.karso.model.*;
|
||||
import org.kar.karso.util.ConfigVariable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
import org.kar.archidata.util.JWTWrapper;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
@ -19,7 +21,9 @@ import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.SecurityContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -31,6 +35,18 @@ import java.time.LocalDateTime;
|
||||
@Produces( MediaType.APPLICATION_JSON)
|
||||
public class UserResource {
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class UserOut {
|
||||
public long id;
|
||||
public String login;
|
||||
public UserOut(long id, String login) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public UserResource() {
|
||||
}
|
||||
@GET
|
||||
@ -47,6 +63,23 @@ public class UserResource {
|
||||
return SqlWrapper.get(UserAuthGet.class, userId);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{userId}/application/{applicationId}/link")
|
||||
@RolesAllowed("ADMIN")
|
||||
public Response linkApplication(@Context SecurityContext sc,
|
||||
@PathParam("userId") long userId,
|
||||
@PathParam("applicationId") long applicationId,
|
||||
boolean data) throws Exception {
|
||||
System.out.println("Find typeNode");
|
||||
if (data == true) {
|
||||
SqlWrapper.addLink(UserAuth.class, userId, "application", applicationId);
|
||||
} else {
|
||||
SqlWrapper.removeLink(UserAuth.class, userId, "application", applicationId);
|
||||
}
|
||||
return Response.ok(SqlWrapper.get(UserAuth.class, userId)).build();
|
||||
}
|
||||
|
||||
// TODO: check this it might be deprecated ...
|
||||
@POST
|
||||
@Path("{id}/set_admin")
|
||||
@RolesAllowed("ADMIN")
|
||||
@ -128,11 +161,11 @@ public class UserResource {
|
||||
@GET
|
||||
@Path("me")
|
||||
@RolesAllowed("USER")
|
||||
public User getMe(@Context SecurityContext sc) {
|
||||
public UserOut getMe(@Context SecurityContext sc) {
|
||||
System.out.println("getMe()");
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
System.out.println("== USER ? " + gc.user);
|
||||
return gc.user;
|
||||
System.out.println("== USER ? " + gc.userByToken);
|
||||
return new UserOut(gc.userByToken.id, gc.userByToken.name);
|
||||
}
|
||||
|
||||
@POST
|
||||
@ -141,7 +174,7 @@ public class UserResource {
|
||||
public Response changePassword(@Context SecurityContext sc, ChangePassword data) throws Exception {
|
||||
System.out.println("ChangePassword()");
|
||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
System.out.println("== USER ? " + gc.user);
|
||||
System.out.println("== USER ? " + gc.userByToken);
|
||||
|
||||
if(data == null) {
|
||||
throw new InputException("data", "No data set...");
|
||||
@ -250,8 +283,22 @@ public class UserResource {
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public GetToken getToken(DataGetToken data) throws Exception {
|
||||
UserAuth user = checkAuthUser(data.method, data.login, data.time, data.password);
|
||||
// at the point the user has been not deleted and not blocked.
|
||||
// this authentication is valid only for Karso ==> not for the application
|
||||
int expirationTimeInMinutes = ConfigVariable.getAuthExpirationTime();
|
||||
String ret = JWTWrapper.generateJWToken(user.id, user.login, "KarAuth", "sso", expirationTimeInMinutes);
|
||||
|
||||
// Get the USER Right (Note: by construction KARSO have application ID = 0
|
||||
Map<String, Object> ssoRight = RightResource.getUserRight(user.id, 0);
|
||||
if (!ssoRight.containsKey("USER")) {
|
||||
// If the USER is not override, the system add by default USER
|
||||
ssoRight.put("USER", true);
|
||||
}
|
||||
System.out.println("Get new token with right: " + ssoRight);
|
||||
Map<String, Object> outRight = new HashMap<>();
|
||||
String applicationName = "karso";
|
||||
// we set the right in the under map to manage multiple application group right. and in some application user can see other user or all user of the application
|
||||
outRight.put(applicationName, ssoRight);
|
||||
String ret = JWTWrapper.generateJWToken(user.id, user.login, "KarAuth", applicationName, outRight, expirationTimeInMinutes);
|
||||
|
||||
// Update last connection:
|
||||
UserAuth newUser = new UserAuth();
|
||||
|
@ -21,6 +21,10 @@ public class KarsoAuthenticationFilter extends AuthenticationFilter {
|
||||
|
||||
//curl http://0.0.0.0:15080/karso/api/public_key/pem --output plop.txt -H "Authorization: Zota 1:U0sJM1m@-STSdfg4365fJOFUGbR4kFycBu1qGZPwf7gW6k2WWRBzTPUH7QutCgPw-SDss45_563sSDFdfg@dsf@456" --verbose
|
||||
|
||||
public KarsoAuthenticationFilter() {
|
||||
super("karso");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserByToken validateToken(String authorization) throws Exception {
|
||||
if (authorization == null || authorization.length() < 25) {
|
||||
|
@ -41,6 +41,10 @@ public class Application extends GenericTable{
|
||||
@SQLComment("Expiration time ")
|
||||
@SQLDefault("666")
|
||||
public Integer ttl;
|
||||
@SQLNotNull
|
||||
@SQLComment("Right is manage with Karso")
|
||||
@SQLDefault("0")
|
||||
public Boolean manageRight;
|
||||
|
||||
public Application() {
|
||||
}
|
||||
@ -58,10 +62,3 @@ public class Application extends GenericTable{
|
||||
'}';
|
||||
}
|
||||
}
|
||||
/*
|
||||
ALTER TABLE `application`
|
||||
CHANGE `description` `description` varchar(2048) COLLATE 'utf8mb4_0900_ai_ci' NULL COMMENT 'description of the application' AFTER `name`,
|
||||
CHANGE `redirect` `redirect` varchar(2048) COLLATE 'latin1_bin' NOT NULL COMMENT 'Token (can be not unique)' AFTER `description`,
|
||||
CHANGE `redirectDev` `redirectDev` varchar(2048) COLLATE 'latin1_bin' NOT NULL DEFAULT 'http://localhost:4200/sso/' AFTER `redirect`,
|
||||
CHANGE `notification` `notification` varchar(2048) COLLATE 'latin1_bin' NOT NULL DEFAULT 'http://localhost:4200/sso/notification' AFTER `redirectDev`;
|
||||
*/
|
@ -10,26 +10,20 @@ CREATE TABLE `application` (
|
||||
|
||||
*/
|
||||
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("application")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class ApplicationSmall{
|
||||
@SQLLimitSize(512)
|
||||
public String name;
|
||||
@SQLLimitSize(512)
|
||||
public String description;
|
||||
@SQLLimitSize(512)
|
||||
@SQLNotNull
|
||||
public String redirect;
|
||||
|
||||
public ApplicationSmall() {
|
||||
}
|
||||
|
||||
public ApplicationSmall(String name, String description, String redirect) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.redirect = redirect;
|
||||
}
|
||||
|
||||
}
|
||||
|
35
back/src/org/kar/karso/model/Right.java
Normal file
35
back/src/org/kar/karso/model/Right.java
Normal file
@ -0,0 +1,35 @@
|
||||
package org.kar.karso.model;
|
||||
|
||||
|
||||
import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLForeignKey;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericTable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("right")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class Right extends GenericTable {
|
||||
|
||||
@SQLNotNull
|
||||
@SQLComment("application-ID that have the reference of the right")
|
||||
@SQLForeignKey("application")
|
||||
public long applicationId;
|
||||
@SQLNotNull
|
||||
@SQLComment("user-ID ")
|
||||
@SQLForeignKey("user")
|
||||
public long userId;
|
||||
@SQLNotNull
|
||||
@SQLComment("rightDescription-ID of the right description")
|
||||
@SQLForeignKey("rightDescription")
|
||||
public long rightDescriptionId;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(1024)
|
||||
@SQLComment("Value of the right")
|
||||
public String value;
|
||||
}
|
39
back/src/org/kar/karso/model/RightDescription.java
Normal file
39
back/src/org/kar/karso/model/RightDescription.java
Normal file
@ -0,0 +1,39 @@
|
||||
package org.kar.karso.model;
|
||||
|
||||
import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLDefault;
|
||||
import org.kar.archidata.annotation.SQLForeignKey;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericTable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("rightDescription")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class RightDescription extends GenericTable {
|
||||
@SQLNotNull
|
||||
@SQLComment("Application id that have the reference of the right")
|
||||
@SQLForeignKey("application")
|
||||
public long applicationId;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(64)
|
||||
@SQLComment("Key of the property")
|
||||
public String key;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(1024)
|
||||
@SQLComment("Title of the right")
|
||||
public String title;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(1024)
|
||||
@SQLComment("Description of the right")
|
||||
public String description;
|
||||
@SQLNotNull
|
||||
@SQLLimitSize(16)
|
||||
@SQLComment("Type of the property")
|
||||
@SQLDefault("\"BOOLEAN\"")
|
||||
public String type = "BOOLEAN"; // this is a place-holder (current type supported BOOLEAN)
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
package org.kar.karso.model;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
import org.kar.archidata.annotation.SQLComment;
|
||||
import org.kar.archidata.annotation.SQLDefault;
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLLimitSize;
|
||||
import org.kar.archidata.annotation.SQLNotNull;
|
||||
import org.kar.archidata.annotation.SQLTableLinkGeneric;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.User;
|
||||
|
||||
@ -35,4 +38,8 @@ public class UserAuth extends User {
|
||||
@SQLDefault("'0'")
|
||||
@SQLNotNull
|
||||
public boolean avatar = false;
|
||||
@SQLComment("List of accessible application (if not set the application is not available)")
|
||||
@SQLTableLinkGeneric
|
||||
public List<Long> applications = null;
|
||||
|
||||
}
|
||||
|
25
back/src/org/kar/karso/model/UserLinkApplication.java
Normal file
25
back/src/org/kar/karso/model/UserLinkApplication.java
Normal file
@ -0,0 +1,25 @@
|
||||
package org.kar.karso.model;
|
||||
|
||||
/*
|
||||
|
||||
CREATE TABLE `application` (
|
||||
`id` bigint NOT NULL COMMENT 'Unique ID of the application' AUTO_INCREMENT PRIMARY KEY,
|
||||
`description` text COMMENT 'description of the application',
|
||||
`token` varchar(128) COLLATE 'latin1_bin' NOT NULL COMMENT 'Token (can be not unique)'
|
||||
) AUTO_INCREMENT=10;
|
||||
|
||||
*/
|
||||
|
||||
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||
import org.kar.archidata.annotation.SQLTableName;
|
||||
import org.kar.archidata.model.GenericTable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
@SQLTableName ("user_link_application")
|
||||
@SQLIfNotExists
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class UserLinkApplication extends GenericTable{
|
||||
public long user_id;
|
||||
public long application_id;
|
||||
}
|
@ -1,22 +1,32 @@
|
||||
package org.kar.karso.util;
|
||||
|
||||
public class ConfigVariable {
|
||||
public static final String BASE_NAME = "ORG_KARAUTH_";
|
||||
public static String BASE_NAME = "ORG_KARAUTH_";
|
||||
public static String frontFolder = System.getenv(BASE_NAME + "FRONT_FOLDER");
|
||||
public static String expirationTime = System.getenv(BASE_NAME + "AUTH_EXPIRATION_TIME");
|
||||
public static String uuid_for_key_generation = System.getenv(BASE_NAME + "UUID_KEY_ROOT");
|
||||
public static String edge = System.getenv(BASE_NAME + "EDGE");
|
||||
|
||||
public static String getFrontFolder() {
|
||||
String out = System.getenv(BASE_NAME + "FRONT_FOLDER");
|
||||
if (out == null) {
|
||||
if (frontFolder == null) {
|
||||
return "/application/front";
|
||||
}
|
||||
return out;
|
||||
return frontFolder;
|
||||
}
|
||||
public static String getUUIDKeyRoot() {
|
||||
return uuid_for_key_generation;
|
||||
}
|
||||
|
||||
public static int getAuthExpirationTime() {
|
||||
String out = System.getenv(BASE_NAME + "AUTH_EXPIRATION_TIME");
|
||||
String out = expirationTime;
|
||||
if (out == null) {
|
||||
// default expiration is 33 days for the master Oauth token
|
||||
return 60*24*33;
|
||||
}
|
||||
return Integer.valueOf(out);
|
||||
}
|
||||
|
||||
public static Boolean getEdge() {
|
||||
return Boolean.valueOf(edge);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"defaultProject": "karso",
|
||||
"projects": {
|
||||
"karso": {
|
||||
"root": "",
|
||||
@ -14,10 +13,13 @@
|
||||
"options": {
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"main": "src/app-root/main.ts",
|
||||
"tsConfig": "src/tsconfig.app-root.json",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"assets": ["src/assets", "src/favicon.ico"],
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.less",
|
||||
"src/generic_page.less",
|
||||
@ -91,7 +93,10 @@
|
||||
"src/theme.checkbox.less",
|
||||
"src/theme.modal.less"
|
||||
],
|
||||
"assets": ["src/assets", "src/favicon.ico"]
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
@ -99,14 +104,22 @@
|
||||
"options": {
|
||||
"fix": true,
|
||||
"eslintConfig": ".eslintrc.js",
|
||||
"lintFilePatterns": ["src/**/*.spec.ts", "src/**/*.ts"]
|
||||
"lintFilePatterns": [
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"TTTTTTlint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,8 +139,89 @@
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": ["e2e/tsconfig.e2e.json"],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"tsConfig": [
|
||||
"e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"karso-edge": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/app-edge/main.ts",
|
||||
"tsConfig": "src/tsconfig.app-edge.json",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.less",
|
||||
"src/generic_page.less",
|
||||
"src/theme.color.blue.less",
|
||||
"src/theme.checkbox.less",
|
||||
"src/theme.modal.less"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.edge.prod.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"develop": {
|
||||
"optimization": false,
|
||||
"outputHashing": "none",
|
||||
"sourceMap": true,
|
||||
"namedChunks": true,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": true,
|
||||
"buildOptimizer": false,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.edge.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "karso:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "karso-edge:build:production"
|
||||
},
|
||||
"develop": {
|
||||
"browserTarget": "karso-edge:build:develop"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
{
|
||||
"name": "karideo",
|
||||
"name": "karso",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"license": "MPL-2",
|
||||
"scripts": {
|
||||
"all": "npm run build && npm run test",
|
||||
"ng": "ng",
|
||||
"start": "ng serve --configuration=develop --watch --port 4200",
|
||||
"build": "ng build --prod",
|
||||
"test": "ng test",
|
||||
"test-coverage": "ng test --code-coverage",
|
||||
"start": "ng serve karso --configuration=develop --watch --port 4200",
|
||||
"start_edge": "ng serve karso-edge --configuration=develop --watch --port 4199",
|
||||
"build": "ng build karso --prod",
|
||||
"test": "ng test karso",
|
||||
"test-coverage": "ng test karso --code-coverage",
|
||||
"lint": "ng lint",
|
||||
"style": "prettier --write .",
|
||||
"e2e": "ng e2e"
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
ManageAccountsScene,
|
||||
ApplicationsScene,
|
||||
ApplicationEditScene,
|
||||
} from './scene';
|
||||
} from '../base/scene';
|
||||
import { OnlyAdminGuard, OnlyUnregisteredGuardHome, OnlyUsersGuard, OnlyUsersGuardHome } from 'common/service/session';
|
||||
import { ForbiddenScene, NotFound404Scene } from 'common/scene';
|
||||
|
161
front/src/app-edge/app.component.ts
Normal file
161
front/src/app-edge/app.component.ts
Normal file
@ -0,0 +1,161 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @license PROPRIETARY (see license file)
|
||||
*/
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { EventOnMenu } from 'common/component/top-menu/top-menu';
|
||||
import { UserService } from 'common/service/user';
|
||||
import { SessionService } from 'common/service/session';
|
||||
import { MenuItem, MenuPosition } from 'common/model/menu-item';
|
||||
import { SSOService } from 'common/service';
|
||||
import { environment } from 'environments/environment';
|
||||
|
||||
enum MenuEventType {
|
||||
SSO_SITE = 'SSO_SITE',
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.less'],
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
title: string = environment.edgeMode ? 'Karso-edge' : 'Karso';
|
||||
autoConnectedDone: boolean = false;
|
||||
isConnected: boolean = false;
|
||||
signUpEnable: boolean = true;
|
||||
currentMenu: MenuItem[] = [];
|
||||
|
||||
constructor(
|
||||
private userService: UserService,
|
||||
private sessionService: SessionService,
|
||||
private ssoService: SSOService
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
console.log(`call with: ${window.location.href}`);
|
||||
this.autoConnectedDone = false;
|
||||
this.isConnected = false;
|
||||
this.updateMainMenu();
|
||||
const self = this;
|
||||
this.sessionService.change.subscribe(isConnected => {
|
||||
console.log(`receive event from session ...${isConnected}`);
|
||||
self.isConnected = isConnected;
|
||||
self.updateMainMenu();
|
||||
});
|
||||
this.userService
|
||||
.checkAutoConnect()
|
||||
.then(() => {
|
||||
console.log(` ==>>>>> Auto-connect THEN !!!`);
|
||||
self.autoConnectedDone = true;
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(` ==>>>>> Auto-connect CATCH !!! ${error}`);
|
||||
self.autoConnectedDone = true;
|
||||
})
|
||||
.finally(() => {
|
||||
console.log(` ==>>>>> Auto-connect FINALLY !!!`);
|
||||
self.autoConnectedDone = true;
|
||||
});
|
||||
this.ssoService
|
||||
.checkSignUpEnable()
|
||||
.then((value: boolean) => {
|
||||
console.log(`Get value signUp = ${value}`);
|
||||
self.signUpEnable = value;
|
||||
self.updateMainMenu();
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log(`Can not call the sso to check the sign-up_interface: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
updateMainMenu(): void {
|
||||
console.log('update main menu :');
|
||||
if (this.isConnected) {
|
||||
console.log(' ==> is connected');
|
||||
this.currentMenu = [
|
||||
{
|
||||
position: MenuPosition.LEFT,
|
||||
hover: `You are logged as: ${this.sessionService.getLogin()}`,
|
||||
icon: 'menu',
|
||||
title: 'Menu',
|
||||
subMenu: [
|
||||
{
|
||||
position: MenuPosition.LEFT,
|
||||
hover: 'Go to Home page',
|
||||
icon: 'home',
|
||||
title: 'Home',
|
||||
navigateTo: 'home',
|
||||
}, {
|
||||
position: MenuPosition.LEFT,
|
||||
hover: 'Exit connection',
|
||||
icon: 'exit_to_app',
|
||||
title: 'Sign out',
|
||||
navigateTo: 'signout',
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
position: MenuPosition.RIGHT,
|
||||
image: 'assets/images/avatar_generic.svg',
|
||||
title: '',
|
||||
subMenu: [
|
||||
{
|
||||
position: MenuPosition.LEFT,
|
||||
hover: `You are logged as: <b>${this.sessionService.getLogin()}</b>`,
|
||||
title: `Sign in as ${this.sessionService.getLogin()}`,
|
||||
}, {
|
||||
position: MenuPosition.LEFT,
|
||||
hover: 'Exit connection',
|
||||
icon: 'exit_to_app',
|
||||
title: 'Sign out',
|
||||
navigateTo: 'signout',
|
||||
}, {
|
||||
position: MenuPosition.RIGHT,
|
||||
hover: 'Create a new account',
|
||||
icon: 'eject',
|
||||
title: 'Parent',
|
||||
navigateTo: 'signup',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
} else {
|
||||
this.currentMenu = [
|
||||
{
|
||||
position: MenuPosition.LEFT,
|
||||
hover: 'Go to Home page',
|
||||
icon: 'home',
|
||||
title: 'Home',
|
||||
navigateTo: 'home',
|
||||
},
|
||||
{
|
||||
position: MenuPosition.RIGHT,
|
||||
hover: 'Create a new account',
|
||||
icon: 'eject',
|
||||
title: 'Parent',
|
||||
callback: true,
|
||||
otherData: MenuEventType.SSO_SITE,
|
||||
},
|
||||
{
|
||||
position: MenuPosition.RIGHT,
|
||||
hover: 'Login page',
|
||||
icon: 'account_circle',
|
||||
title: 'Sign-in',
|
||||
navigateTo: 'signin',
|
||||
},
|
||||
];
|
||||
}
|
||||
console.log(' ==> DONE');
|
||||
}
|
||||
|
||||
eventOnMenu(data: EventOnMenu): void {
|
||||
switch (data.menu.otherData) {
|
||||
case MenuEventType.SSO_SITE:
|
||||
this.ssoService.requestOpenSite();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ import {
|
||||
ManageAccountsScene,
|
||||
ApplicationsScene,
|
||||
ApplicationEditScene,
|
||||
} from 'app/scene';
|
||||
} from 'base/scene';
|
||||
import {
|
||||
BddService,
|
||||
CookiesService,
|
||||
@ -44,7 +44,7 @@ import {
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ErrorComponent, PopInComponent, SpinerComponent, TopMenuComponent, UploadFileComponent, PasswordEntryComponent, EntryComponent, AsyncActionStatusComponent, ErrorMessageStateComponent, CheckboxComponent, BurgerPropertyComponent, EntryValidatorComponent, RenderSettingsComponent, RenderFormComponent, EntryNumberComponent } from 'common/component';
|
||||
import { ForbiddenScene } from 'common/scene';
|
||||
import { AdminUserService, ApplicationService, ApplicationTokenService, SettingsService } from 'app/service';
|
||||
import { AdminUserService, ApplicationService, ApplicationTokenService, SettingsService } from 'base/service';
|
||||
import { PopInUploadProgress, PopInDeleteConfirm } from 'common/popin';
|
||||
|
||||
@NgModule({
|
@ -1,8 +1,8 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
import { AppModule } from './app.module';
|
||||
import { environment } from '../environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
101
front/src/app-root/app-routing.module.ts
Normal file
101
front/src/app-root/app-routing.module.ts
Normal file
@ -0,0 +1,101 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2022, Edouard DUPIN, all right reserved
|
||||
* @license PROPRIETARY (see license file)
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router'; // CLI imports router
|
||||
import {
|
||||
ChangePasswordScene,
|
||||
ForgotPasswordScene,
|
||||
HelpScene,
|
||||
HomeScene,
|
||||
SettingsScene,
|
||||
SignInScene,
|
||||
SignOutScene,
|
||||
SignUpScene,
|
||||
HomeUnregisteredScene,
|
||||
ManageAccountsScene,
|
||||
ApplicationsScene,
|
||||
ApplicationEditScene,
|
||||
} from '../base/scene';
|
||||
import { OnlyAdminGuard, OnlyUnregisteredGuardHome, OnlyUsersGuard, OnlyUsersGuardHome } from 'common/service/session';
|
||||
import { ForbiddenScene, NotFound404Scene } from 'common/scene';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
||||
|
||||
{ path: 'forbidden', component: ForbiddenScene },
|
||||
|
||||
// ------------------------------------
|
||||
// -- home global interface
|
||||
// ------------------------------------
|
||||
{
|
||||
path: 'home',
|
||||
component: HomeScene,
|
||||
canActivate: [OnlyUsersGuardHome], // this route to unregistered path when not logged ==> permit to simplify display
|
||||
},
|
||||
{
|
||||
path: 'unregistered',
|
||||
component: HomeUnregisteredScene,
|
||||
canActivate: [OnlyUnregisteredGuardHome], // jump to the home when registered
|
||||
},
|
||||
|
||||
{ path: 'forgot-password', component: ForgotPasswordScene },
|
||||
{ path: 'help/:page', component: HelpScene },
|
||||
{ path: 'help', component: HelpScene },
|
||||
|
||||
{ path: 'signin', component: SignInScene },
|
||||
// SSO connection mode ==> redirect to the second part data package
|
||||
{ path: 'signin/:applicationId/:dataReturn', component: SignInScene },
|
||||
{ path: 'signin/:applicationId', component: SignInScene },
|
||||
|
||||
{ path: 'signup', component: SignUpScene },
|
||||
{ path: 'signup/:applicationId/:dataReturn', component: SignUpScene },
|
||||
{ path: 'signup/:applicationId', component: SignUpScene },
|
||||
|
||||
{ path: 'signout/:applicationId/:dataReturn', component: SignOutScene },
|
||||
{ path: 'signout/:applicationId', component: SignOutScene },
|
||||
{ path: 'signout', component: SignOutScene },
|
||||
|
||||
{
|
||||
path: 'password',
|
||||
component: ChangePasswordScene,
|
||||
canActivate: [OnlyUsersGuard],
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
component: SettingsScene,
|
||||
canActivate: [OnlyAdminGuard],
|
||||
},
|
||||
{
|
||||
path: 'manage_accounts',
|
||||
component: ManageAccountsScene,
|
||||
canActivate: [OnlyAdminGuard],
|
||||
},
|
||||
{
|
||||
path: 'applications',
|
||||
component: ApplicationsScene,
|
||||
canActivate: [OnlyAdminGuard],
|
||||
},
|
||||
{
|
||||
path: 'application-edit/:applicationId',
|
||||
component: ApplicationEditScene,
|
||||
canActivate: [OnlyAdminGuard],
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
component: NotFound404Scene,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forRoot(routes, {
|
||||
//enableTracing: true, // <-- debugging purposes only
|
||||
}),
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AppRoutingModule { }
|
6
front/src/app-root/app.component.html
Normal file
6
front/src/app-root/app.component.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!-- Generig global menu -->
|
||||
<app-top-menu [menu]="currentMenu" (callback)="eventOnMenu($event)"></app-top-menu>
|
||||
<!-- all interfaced pages -->
|
||||
<div class="main-content">
|
||||
<router-outlet *ngIf="autoConnectedDone"></router-outlet>
|
||||
</div>
|
44
front/src/app-root/app.component.less
Normal file
44
front/src/app-root/app.component.less
Normal file
@ -0,0 +1,44 @@
|
||||
#create-exercice-button {
|
||||
position: fixed;
|
||||
display: block;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin-right: 40px;
|
||||
margin-bottom: 40px;
|
||||
z-index: 900;
|
||||
}
|
||||
|
||||
#save-exercice-button {
|
||||
position: fixed;
|
||||
display: block;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin-right: 110px;
|
||||
margin-bottom: 40px;
|
||||
z-index: 900;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
position: absolute;
|
||||
//width: ~"calc(calc(100% / 5 ) * 5)";
|
||||
width: 100%;
|
||||
height: ~'calc(100% - 56px)';
|
||||
top: 56px;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
position: fixed;
|
||||
overflow-y: auto;
|
||||
//background-color:#FF0;
|
||||
/*
|
||||
.main-reduce {
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0px 10% 0px 10%;
|
||||
display: block;
|
||||
overflow-y:scroll;
|
||||
}
|
||||
*/
|
||||
}
|
@ -7,9 +7,10 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { EventOnMenu } from 'common/component/top-menu/top-menu';
|
||||
import { UserService } from 'common/service/user';
|
||||
import { SessionService } from 'common/service/session';
|
||||
import { SessionService, UserRoles222 } from 'common/service/session';
|
||||
import { MenuItem, MenuPosition } from 'common/model/menu-item';
|
||||
import { SSOService } from 'common/service';
|
||||
import { environment } from 'environments/environment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@ -17,7 +18,7 @@ import { SSOService } from 'common/service';
|
||||
styleUrls: ['./app.component.less'],
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
title: string = 'Karideo';
|
||||
title: string = environment.edgeMode ? 'Karso-edge' : 'Karso';
|
||||
autoConnectedDone: boolean = false;
|
||||
isConnected: boolean = false;
|
||||
signUpEnable: boolean = true;
|
||||
@ -34,7 +35,7 @@ export class AppComponent implements OnInit {
|
||||
this.autoConnectedDone = false;
|
||||
this.isConnected = false;
|
||||
this.updateMainMenu();
|
||||
let self = this;
|
||||
const self = this;
|
||||
this.sessionService.change.subscribe(isConnected => {
|
||||
console.log(`receive event from session ...${isConnected}`);
|
||||
self.isConnected = isConnected;
|
||||
@ -43,15 +44,15 @@ export class AppComponent implements OnInit {
|
||||
this.userService
|
||||
.checkAutoConnect()
|
||||
.then(() => {
|
||||
console.log(` ==>>>>> Autoconnect THEN !!!`);
|
||||
console.log(` ==>>>>> Auto-connect THEN !!!`);
|
||||
self.autoConnectedDone = true;
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(` ==>>>>> Autoconnect CATCH !!! ${error}`);
|
||||
console.log(` ==>>>>> Auto-connect CATCH !!! ${error}`);
|
||||
self.autoConnectedDone = true;
|
||||
})
|
||||
.finally(() => {
|
||||
console.log(` ==>>>>> Autoconnect FINALLY !!!`);
|
||||
console.log(` ==>>>>> Auto-connect FINALLY !!!`);
|
||||
self.autoConnectedDone = true;
|
||||
});
|
||||
this.ssoService
|
||||
@ -104,28 +105,28 @@ export class AppComponent implements OnInit {
|
||||
icon: 'settings',
|
||||
title: 'Admin Settings',
|
||||
navigateTo: 'settings',
|
||||
enable: this.sessionService.userAdmin === true,
|
||||
enable: this.sessionService.hasRight(UserRoles222.admin),
|
||||
}, { // TODO move this in the setting environment system ?
|
||||
position: MenuPosition.LEFT,
|
||||
hover: 'Admin of users',
|
||||
icon: 'manage_accounts',
|
||||
title: 'Manage Accounts',
|
||||
navigateTo: 'manage_accounts',
|
||||
enable: this.sessionService.userAdmin === true,
|
||||
enable: this.sessionService.hasRight(UserRoles222.admin),
|
||||
}, {
|
||||
position: MenuPosition.LEFT,
|
||||
hover: 'Admin of all the applications',
|
||||
icon: 'app_registration',
|
||||
title: 'Manage Applications',
|
||||
navigateTo: 'applications',
|
||||
enable: this.sessionService.userAdmin === true,
|
||||
enable: this.sessionService.hasRight(UserRoles222.admin),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
position: MenuPosition.RIGHT,
|
||||
image: "assets/images/avatar_generic.svg",
|
||||
title: "",
|
||||
image: 'assets/images/avatar_generic.svg',
|
||||
title: '',
|
||||
subMenu: [
|
||||
{
|
||||
position: MenuPosition.LEFT,
|
||||
@ -138,13 +139,13 @@ export class AppComponent implements OnInit {
|
||||
navigateTo: "settings",
|
||||
}, */{
|
||||
position: MenuPosition.LEFT,
|
||||
icon: "help",
|
||||
title: "Help",
|
||||
navigateTo: "help",
|
||||
icon: 'help',
|
||||
title: 'Help',
|
||||
navigateTo: 'help',
|
||||
}, {
|
||||
position: MenuPosition.LEFT,
|
||||
hover: "Exit connection",
|
||||
icon: "exit_to_app",
|
||||
hover: 'Exit connection',
|
||||
icon: 'exit_to_app',
|
||||
title: 'Sign out',
|
||||
navigateTo: 'signout',
|
||||
},
|
137
front/src/app-root/app.module.ts
Normal file
137
front/src/app-root/app.module.ts
Normal file
@ -0,0 +1,137 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @license PROPRIETARY (see license file)
|
||||
*/
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; // this is needed for dynamic selection of the select
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import {
|
||||
SignInScene,
|
||||
SignUpScene,
|
||||
ValidateEmailScene,
|
||||
HomeScene,
|
||||
ErrorViewerScene,
|
||||
ForgotPasswordScene,
|
||||
HelpScene,
|
||||
SignOutScene,
|
||||
ChangePasswordScene,
|
||||
SettingsScene,
|
||||
HomeUnregisteredScene,
|
||||
ManageAccountsScene,
|
||||
ApplicationsScene,
|
||||
ApplicationEditScene,
|
||||
} from 'base/scene';
|
||||
import {
|
||||
BddService,
|
||||
CookiesService,
|
||||
HttpWrapperService,
|
||||
NotificationService,
|
||||
OnlyAdminGuard,
|
||||
OnlyUnregisteredGuardHome,
|
||||
OnlyUsersGuard,
|
||||
OnlyUsersGuardHome,
|
||||
PopInService,
|
||||
SessionService,
|
||||
SSOService,
|
||||
StorageService,
|
||||
UserService,
|
||||
} from 'common/service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ErrorComponent, PopInComponent, SpinerComponent, TopMenuComponent, UploadFileComponent, PasswordEntryComponent, EntryComponent, AsyncActionStatusComponent, ErrorMessageStateComponent, CheckboxComponent, BurgerPropertyComponent, EntryValidatorComponent, RenderSettingsComponent, RenderFormComponent, EntryNumberComponent } from 'common/component';
|
||||
import { ForbiddenScene } from 'common/scene';
|
||||
import { AdminUserService, ApplicationService, ApplicationTokenService, SettingsService } from 'base/service';
|
||||
import { PopInUploadProgress, PopInDeleteConfirm } from 'common/popin';
|
||||
import { environment } from 'environments/environment';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TopMenuComponent,
|
||||
UploadFileComponent,
|
||||
ErrorComponent,
|
||||
PasswordEntryComponent,
|
||||
EntryComponent,
|
||||
EntryValidatorComponent,
|
||||
SpinerComponent,
|
||||
AsyncActionStatusComponent,
|
||||
ErrorMessageStateComponent,
|
||||
CheckboxComponent,
|
||||
BurgerPropertyComponent,
|
||||
RenderSettingsComponent,
|
||||
RenderFormComponent,
|
||||
EntryNumberComponent,
|
||||
|
||||
PopInComponent,
|
||||
PopInUploadProgress,
|
||||
PopInDeleteConfirm,
|
||||
|
||||
SignInScene,
|
||||
SignUpScene,
|
||||
SignOutScene,
|
||||
ValidateEmailScene,
|
||||
HomeScene,
|
||||
ErrorViewerScene,
|
||||
HelpScene,
|
||||
ForgotPasswordScene,
|
||||
SettingsScene,
|
||||
ForbiddenScene,
|
||||
ChangePasswordScene,
|
||||
HomeUnregisteredScene,
|
||||
ManageAccountsScene,
|
||||
ApplicationsScene,
|
||||
ApplicationEditScene
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
RouterModule,
|
||||
AppRoutingModule,
|
||||
HttpClientModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
CommonModule,
|
||||
],
|
||||
// injectable element
|
||||
providers: [
|
||||
// application
|
||||
AdminUserService,
|
||||
ApplicationService,
|
||||
ApplicationTokenService,
|
||||
|
||||
// common
|
||||
BddService,
|
||||
CookiesService,
|
||||
HttpWrapperService,
|
||||
StorageService,
|
||||
PopInService,
|
||||
SessionService,
|
||||
UserService,
|
||||
SSOService,
|
||||
NotificationService,
|
||||
SettingsService,
|
||||
OnlyUsersGuard,
|
||||
OnlyAdminGuard,
|
||||
OnlyUsersGuardHome,
|
||||
OnlyUnregisteredGuardHome,
|
||||
],
|
||||
exports: [
|
||||
AppComponent,
|
||||
TopMenuComponent,
|
||||
PasswordEntryComponent,
|
||||
UploadFileComponent,
|
||||
ErrorComponent,
|
||||
BurgerPropertyComponent,
|
||||
|
||||
BurgerPropertyComponent,
|
||||
PopInComponent,
|
||||
PopInUploadProgress,
|
||||
PopInDeleteConfirm,
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
|
||||
})
|
||||
export class AppModule { }
|
15
front/src/app-root/main.ts
Normal file
15
front/src/app-root/main.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
import { environment } from '../environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch(err => {
|
||||
return console.log(err);
|
||||
});
|
@ -6,8 +6,8 @@
|
||||
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ApplicationService, ApplicationModel, ApplicationTokenService } from 'app/service';
|
||||
import { ApplicationTokenModel } from 'app/service/application-token';
|
||||
import { ApplicationService, ApplicationModel, ApplicationTokenService } from 'base/service';
|
||||
import { ApplicationTokenModel } from 'base/service/application-token';
|
||||
import { AsyncActionState } from 'common/component';
|
||||
import { CheckerParameterType, SettingsItem, SettingType } from 'common/component/render-settings/render-settings';
|
||||
import { NotificationService, PopInService } from 'common/service';
|
@ -4,6 +4,7 @@
|
||||
<burger-property>
|
||||
<name>Applications</name>
|
||||
<description>Availlable applications for this SSO</description>
|
||||
|
||||
<body>
|
||||
<table class="table-model">
|
||||
<tr>
|
||||
@ -23,16 +24,13 @@
|
||||
<td>{{application.ttl}}</td>
|
||||
<td>{{application.notification}}</td>
|
||||
<td>
|
||||
<button
|
||||
class="square-button login color-shadow-black"
|
||||
(click)="onEditApplication($event, application)"
|
||||
type="submit">
|
||||
<button class="square-button login color-shadow-black"
|
||||
(click)="onEditApplication($event, application)" type="submit">
|
||||
<i class="material-icons">edit</i>
|
||||
</button>
|
||||
<button
|
||||
<button *ngIf="application.id !== 0"
|
||||
class="square-button login color-button-cancel color-shadow-black"
|
||||
(click)="onRemoveApplication($event, application)"
|
||||
type="submit">
|
||||
(click)="onRemoveApplication($event, application)" type="submit">
|
||||
<i class="material-icons">delete_forever</i>
|
||||
</button>
|
||||
</td>
|
||||
@ -46,19 +44,14 @@
|
||||
<burger-property>
|
||||
<name>Create new application</name>
|
||||
<description>Add a new application on the server</description>
|
||||
|
||||
<body>
|
||||
<app-render-form
|
||||
[values]="createApplicationMenu"
|
||||
(deltaValues)="onCreateValueDeltaValues($event)"
|
||||
(changeState)="onCreateValueState($event)"
|
||||
></app-render-form>
|
||||
<app-render-form [values]="createApplicationMenu" (deltaValues)="onCreateValueDeltaValues($event)"
|
||||
(changeState)="onCreateValueState($event)"></app-render-form>
|
||||
</body>
|
||||
<footer>
|
||||
<button
|
||||
class="button login color-button-validate color-shadow-black"
|
||||
id="create-button"
|
||||
[disabled]="validateButtonCreateApplicationDisabled !== 0"
|
||||
(click)="onCreateApplication()"
|
||||
<button class="button login color-button-validate color-shadow-black" id="create-button"
|
||||
[disabled]="validateButtonCreateApplicationDisabled !== 0" (click)="onCreateApplication()"
|
||||
type="submit">
|
||||
Create application
|
||||
</button>
|
||||
@ -68,6 +61,4 @@
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<delete-confirm
|
||||
[comment]="confirmDeleteComment"
|
||||
(callback)="deleteConfirmed()"></delete-confirm>
|
||||
<delete-confirm [comment]="confirmDeleteComment" (callback)="deleteConfirmed()"></delete-confirm>
|
@ -6,7 +6,7 @@
|
||||
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { ApplicationService, ApplicationModel } from 'app/service';
|
||||
import { ApplicationService, ApplicationModel } from 'base/service';
|
||||
import { AsyncActionState } from 'common/component';
|
||||
import { CheckerParameterType, SettingsItem, SettingType } from 'common/component/render-settings/render-settings';
|
||||
import { NotificationService, PopInService } from 'common/service';
|
@ -7,7 +7,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { createPasswordState } from 'common/utils';
|
||||
import { AdminUserService } from 'app/service';
|
||||
import { AdminUserService } from 'base/service';
|
||||
|
||||
export enum PasswordState {
|
||||
FILLING = "filling",
|
@ -8,7 +8,7 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Location } from '@angular/common';
|
||||
import { UserService } from 'common/service';
|
||||
import { AdminUserService } from 'app/service';
|
||||
import { AdminUserService } from 'base/service';
|
||||
|
||||
export function checkLoginValidity(value: string): boolean {
|
||||
let regexCheck = new RegExp('^[a-zA-Z0-9_\\.-]+$');
|
@ -5,8 +5,8 @@
|
||||
*/
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApplicationService } from 'app/service';
|
||||
import { GetApplicationSmallResponse, SpecificTokenResponse } from 'app/service/application';
|
||||
import { ApplicationService } from 'base/service';
|
||||
import { GetApplicationSmallResponse, SpecificTokenResponse } from 'base/service/application';
|
||||
import { UserService } from 'common/service';
|
||||
|
||||
@Component({
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||
import { AdminUserService } from 'app/service';
|
||||
import { AdminUserService } from 'base/service';
|
||||
import { AsyncActionState } from 'common/component';
|
||||
import { SessionService } from 'common/service';
|
||||
import {
|
@ -6,7 +6,7 @@
|
||||
|
||||
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { SettingsService } from 'app/service';
|
||||
import { SettingsService } from 'base/service';
|
||||
import { isSettingsItem, SettingsItem, SettingType } from 'common/component/render-settings/render-settings';
|
||||
import {
|
||||
isNullOrUndefined,
|
@ -9,8 +9,8 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Location } from '@angular/common';
|
||||
import { SessionService } from 'common/service';
|
||||
import { createLoginState, createPasswordState, getLoginType, isNullOrUndefined } from 'common/utils';
|
||||
import { AdminUserService, ApplicationService } from 'app/service';
|
||||
import { SpecificTokenResponse } from 'app/service/application';
|
||||
import { AdminUserService, ApplicationService } from 'base/service';
|
||||
import { SpecificTokenResponse } from 'base/service/application';
|
||||
|
||||
|
||||
@Component({
|
@ -9,8 +9,8 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Location } from '@angular/common';
|
||||
import { UserService } from 'common/service/user';
|
||||
import { isNullOrUndefined } from 'common/utils';
|
||||
import { AdminUserService, ApplicationService } from 'app/service';
|
||||
import { SpecificReturnResponse } from 'app/service/application';
|
||||
import { AdminUserService, ApplicationService } from 'base/service';
|
||||
import { SpecificReturnResponse } from 'base/service/application';
|
||||
|
||||
export function checkLoginValidity(value: string): boolean {
|
||||
let regexCheck = new RegExp('^[a-zA-Z0-9_\\.-]+$');
|
@ -7,7 +7,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { SSOService, UserService } from 'common/service';
|
||||
import { AdminUserService } from 'app/service';
|
||||
import { AdminUserService } from 'base/service';
|
||||
import { checkLoginValidity, checkEmailValidity, checkPasswordValidity } from '../forgot-password/forgot-password';
|
||||
|
||||
@Component({
|
@ -23,7 +23,7 @@ interface MessageLogIn {
|
||||
time: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
/*
|
||||
interface MessageAnswer_USER_CONNECT {
|
||||
sessionId: string;
|
||||
login: string;
|
||||
@ -31,6 +31,7 @@ interface MessageAnswer_USER_CONNECT {
|
||||
role: string;
|
||||
avatar: string;
|
||||
}
|
||||
*/
|
||||
|
||||
@Injectable()
|
||||
export class AdminUserService {
|
||||
@ -55,7 +56,7 @@ export class AdminUserService {
|
||||
private loginSha(login: string, password: string, rememberMe?: boolean): Promise<boolean> {
|
||||
// remove the current session interface
|
||||
this.userService.removeSession();
|
||||
let self = this;
|
||||
const self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
self.getTocken(login, password)
|
||||
.then((value: any) => {
|
||||
@ -82,7 +83,7 @@ export class AdminUserService {
|
||||
// TODO: skip this part if the token is valid !!!
|
||||
// this is here we need to route to the SSO on external system.
|
||||
|
||||
let currentDate: string = new Date().toISOString();
|
||||
const currentDate: string = new Date().toISOString();
|
||||
let data: MessageLogIn;
|
||||
// create request:
|
||||
if (this.identificationVersion === 1) {
|
||||
@ -139,7 +140,7 @@ export class AdminUserService {
|
||||
|
||||
|
||||
setAdmin(userId: number, state: boolean): Promise<void> {
|
||||
let body = state;
|
||||
const body = state;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http
|
||||
.requestJson({
|
||||
@ -160,7 +161,7 @@ export class AdminUserService {
|
||||
}
|
||||
|
||||
setBlocked(userId: number, state: boolean): Promise<void> {
|
||||
let body = state;
|
||||
const body = state;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http
|
||||
.requestJson({
|
||||
@ -181,7 +182,7 @@ export class AdminUserService {
|
||||
}
|
||||
|
||||
createUsers(email: string, login: string, password: string): Promise<any> {
|
||||
let body = {
|
||||
const body = {
|
||||
email,
|
||||
login,
|
||||
password: sha512(password)
|
||||
@ -210,7 +211,7 @@ export class AdminUserService {
|
||||
return this.createSha(login, email, sha512(password));
|
||||
}
|
||||
createSha(login: string, email: string, password: string) {
|
||||
let data = {
|
||||
const data = {
|
||||
method: 'v?',
|
||||
login: login,
|
||||
email: email,
|
||||
@ -244,7 +245,7 @@ export class AdminUserService {
|
||||
}
|
||||
|
||||
checkLogin(login: string): Promise<boolean> {
|
||||
let params = {
|
||||
const params = {
|
||||
login: login,
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -274,7 +275,7 @@ export class AdminUserService {
|
||||
}
|
||||
|
||||
checkEMail(email: string): Promise<boolean> {
|
||||
let params = {
|
||||
const params = {
|
||||
email: email,
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -307,8 +308,8 @@ export class AdminUserService {
|
||||
}
|
||||
|
||||
changePassword(oldPassword: string, newPassword: string): Promise<void> {
|
||||
let time: string = new Date().toISOString();
|
||||
let login: string = this.sessionService.getLogin();
|
||||
const time: string = new Date().toISOString();
|
||||
const login: string = this.sessionService.getLogin();
|
||||
let method = null;
|
||||
let password = null;
|
||||
if (this.identificationVersion === 1) {
|
||||
@ -319,14 +320,14 @@ export class AdminUserService {
|
||||
reject(`Internal Fail (contact administrator).`);
|
||||
});
|
||||
}
|
||||
let body = {
|
||||
const body = {
|
||||
method,
|
||||
time,
|
||||
login,
|
||||
password,
|
||||
newPassword: sha512(newPassword),
|
||||
}
|
||||
let self = this;
|
||||
};
|
||||
const self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
self.http
|
||||
.request({
|
@ -122,7 +122,6 @@ export class SettingsService {
|
||||
for (let key of keys) {
|
||||
this.set(key, data[key])
|
||||
.then((result: boolean) => {
|
||||
|
||||
multipleResponse.add(key, result);
|
||||
})
|
||||
.catch((error: any) => {
|
@ -6,22 +6,21 @@
|
||||
|
||||
import { Injectable, Output, EventEmitter } from '@angular/core';
|
||||
import { CanActivate, Router } from '@angular/router';
|
||||
import { isNullOrUndefined } from 'common/utils';
|
||||
import { environment } from 'environments/environment';
|
||||
|
||||
export enum UserRoles222 {
|
||||
admin = 10000,
|
||||
user = 1,
|
||||
guest = 10,
|
||||
admin = 'admin',
|
||||
user = 'user',
|
||||
guest = 'guest',
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private tokenJwt = null;
|
||||
public sessionId = null;
|
||||
public userLogin = null;
|
||||
public userAdmin = null;
|
||||
public userEMail = null;
|
||||
public userAvatar = null;
|
||||
public userId = null;
|
||||
public right: any = {};
|
||||
|
||||
@Output() change: EventEmitter<boolean> = new EventEmitter();
|
||||
|
||||
@ -30,74 +29,74 @@ export class SessionService {
|
||||
/**
|
||||
* @brief Create a new session.
|
||||
*
|
||||
* @param sessionId -
|
||||
* @param userId -
|
||||
* @param userLogin -
|
||||
* @param userEMail -
|
||||
* @param userAdmin -
|
||||
* @param userAvatar -
|
||||
* @param tokenJwt -
|
||||
*/
|
||||
create({
|
||||
sessionId,
|
||||
userId,
|
||||
userLogin,
|
||||
userEMail,
|
||||
userAdmin,
|
||||
userAvatar,
|
||||
tokenJwt,
|
||||
}: {
|
||||
sessionId;
|
||||
userId: string;
|
||||
userLogin: string;
|
||||
userEMail: string;
|
||||
userAdmin: boolean;
|
||||
userBlocked: boolean;
|
||||
userRemoved: boolean;
|
||||
userAvatar: string;
|
||||
tokenJwt: string;
|
||||
}) {
|
||||
console.log(
|
||||
`Session Create: userId=${userId} userLogin=${userLogin} userEMail=${userEMail} userAdmin=${userAdmin} userAvatar=${userAvatar} sessionId = ${sessionId} tokenJwt = ${tokenJwt}`
|
||||
`Session Create: userId=${userId} userLogin=${userLogin} tokenJwt = ${tokenJwt}`
|
||||
);
|
||||
this.tokenJwt = tokenJwt;
|
||||
this.sessionId = sessionId;
|
||||
this.userId = userId;
|
||||
this.userLogin = userLogin;
|
||||
this.userAdmin = userAdmin;
|
||||
this.userEMail = userEMail;
|
||||
this.userAvatar = userAvatar;
|
||||
this.right = this.parseToken(tokenJwt);
|
||||
console.log(`Retrieve right: ${JSON.stringify(this.right, null, 4)}`);
|
||||
this.change.emit(true);
|
||||
}
|
||||
|
||||
b64_to_utf8(str: string): string {
|
||||
return decodeURIComponent(window.atob(str));
|
||||
}
|
||||
parseToken(token: string): any {
|
||||
const cut = token.split('.');
|
||||
const decoded = this.b64_to_utf8(cut[1]);
|
||||
const jsonModel = JSON.parse(decoded);
|
||||
if (isNullOrUndefined(jsonModel.right)) {
|
||||
return {};
|
||||
}
|
||||
if (isNullOrUndefined(jsonModel.right[environment.applName])) {
|
||||
return {};
|
||||
}
|
||||
return jsonModel.right[environment.applName];
|
||||
}
|
||||
/**
|
||||
* @brief destroy the current session.
|
||||
*/
|
||||
destroy() {
|
||||
console.log('Session REMOVE');
|
||||
let last = this.sessionId;
|
||||
this.sessionId = null;
|
||||
this.tokenJwt = undefined;
|
||||
this.userId = null;
|
||||
this.userLogin = null;
|
||||
this.userAdmin = null;
|
||||
this.userEMail = null;
|
||||
this.userAvatar = null;
|
||||
this.right = {};
|
||||
this.change.emit(false);
|
||||
}
|
||||
getToken(): string | undefined {
|
||||
return this.tokenJwt;
|
||||
}
|
||||
islogged() {
|
||||
return this.sessionId !== null;
|
||||
return this.userId !== null;
|
||||
}
|
||||
hasRight(type) {
|
||||
hasRight(type: UserRoles222): boolean {
|
||||
if (type === UserRoles222.admin) {
|
||||
// sometime needed...
|
||||
return this.userAdmin;
|
||||
if (isNullOrUndefined(this.right.ADMIN)) {
|
||||
return false;
|
||||
}
|
||||
return this.right.ADMIN;
|
||||
}
|
||||
if (type === UserRoles222.user) {
|
||||
// is connected ==> is user
|
||||
return this.sessionId !== null;
|
||||
if (isNullOrUndefined(this.right.USER)) {
|
||||
return false;
|
||||
}
|
||||
return this.right.USER;
|
||||
}
|
||||
if (type === UserRoles222.guest) {
|
||||
// all the other ... maybe unneeded
|
||||
|
@ -44,7 +44,7 @@ export class SSOService {
|
||||
) {
|
||||
return this.utf8_to_b64(data);
|
||||
}
|
||||
let pathName = getApplicationLocation();
|
||||
const pathName = getApplicationLocation();
|
||||
if (isInArray(pathName, ['sso', '/sso', '/sso/'])) {
|
||||
return this.utf8_to_b64('home');
|
||||
}
|
||||
@ -80,6 +80,12 @@ export class SSOService {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/**
|
||||
* Request Open SSO Global website
|
||||
*/
|
||||
requestOpenSite(): void {
|
||||
window.location.href = environment.ssoSite;
|
||||
}
|
||||
/**
|
||||
* Request SSO connection
|
||||
*/
|
||||
|
@ -14,13 +14,13 @@ import { SessionService } from './session';
|
||||
import { SSOService } from './sso';
|
||||
import { getApplicationLocation, isNullOrUndefined, sha512 } from 'common/utils';
|
||||
|
||||
/*
|
||||
interface MessageLogIn {
|
||||
login: string;
|
||||
method: string;
|
||||
time: number;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface MessageAnswer_USER_CONNECT {
|
||||
sessionId: string;
|
||||
login: string;
|
||||
@ -28,7 +28,7 @@ interface MessageAnswer_USER_CONNECT {
|
||||
role: string;
|
||||
avatar: string;
|
||||
}
|
||||
|
||||
*/
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
// 0: Not hide password; 1 hide password;
|
||||
@ -91,7 +91,7 @@ export class UserService {
|
||||
*/
|
||||
checkAutoConnect(): Promise<void> {
|
||||
let locationOrigin = getApplicationLocation();
|
||||
let self = this;
|
||||
const self = this;
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
// Need to use the windows global route to prevent the log in cycle ...
|
||||
// And in the mlain application position, the route does not have curently root the page
|
||||
@ -154,7 +154,7 @@ export class UserService {
|
||||
}
|
||||
|
||||
startSession(token: string, rememberMe: boolean): Promise<string> {
|
||||
let self = this;
|
||||
const self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
self.retreiveMe(token)
|
||||
.then((value2: boolean) => {
|
||||
@ -178,7 +178,7 @@ export class UserService {
|
||||
}
|
||||
retreiveMe(token: string): Promise<boolean> {
|
||||
console.log(`AuthService.loginWithToken ... '${token}'`);
|
||||
let self = this;
|
||||
const self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http
|
||||
.requestJson({
|
||||
@ -193,14 +193,14 @@ export class UserService {
|
||||
// TODO: check type ...
|
||||
console.log(`loginWithToken : get some data to check: ${JSON.stringify(response.data)}`);
|
||||
self.sessionService.create({
|
||||
sessionId: response.data.sessionId,
|
||||
//sessionId: response.data.sessionId,
|
||||
userId: response.data.id,
|
||||
userLogin: response.data.login,
|
||||
userEMail: response.data.email,
|
||||
userAdmin: response.data.admin,
|
||||
userBlocked: response.data.blocked,
|
||||
userRemoved: response.data.removed,
|
||||
userAvatar: response.data.avatar,
|
||||
//userEMail: response.data.email,
|
||||
//userAdmin: response.data.admin,
|
||||
//userBlocked: response.data.blocked,
|
||||
//userRemoved: response.data.removed,
|
||||
//userAvatar: response.data.avatar,
|
||||
tokenJwt: token,
|
||||
});
|
||||
resolve(true);
|
||||
|
21
front/src/environments/environment.edge.prod.ts
Normal file
21
front/src/environments/environment.edge.prod.ts
Normal file
@ -0,0 +1,21 @@
|
||||
// The file contents for the current environment will overwrite these during build.
|
||||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
||||
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
||||
|
||||
export const environment = {
|
||||
production: true,
|
||||
// URL of development API
|
||||
applName: 'karso',
|
||||
defaultServer: 'karso',
|
||||
server: {
|
||||
karso: `${location.origin}/karso/api`,
|
||||
},
|
||||
edgeMode: true,
|
||||
// set to undefined sso* in case of internal authentication model
|
||||
ssoSite: `${location.origin}/karso-edge`,
|
||||
ssoSignIn: undefined,
|
||||
ssoSignOut: undefined,
|
||||
ssoSignUp: undefined,
|
||||
tokenStoredInPermanentStorage: true,
|
||||
};
|
21
front/src/environments/environment.edge.ts
Normal file
21
front/src/environments/environment.edge.ts
Normal file
@ -0,0 +1,21 @@
|
||||
// The file contents for the current environment will overwrite these during build.
|
||||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
||||
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
// URL of development API
|
||||
applName: 'karso-edge',
|
||||
defaultServer: 'karso',
|
||||
server: {
|
||||
karso: 'http://localhost:15080/karso-edge/api',
|
||||
},
|
||||
edgeMode: true,
|
||||
// set to undefined sso* in case of internal authentication model
|
||||
ssoSite: 'http://localhost:15080/karso',
|
||||
ssoSignIn: undefined,
|
||||
ssoSignOut: undefined,
|
||||
ssoSignUp: undefined,
|
||||
tokenStoredInPermanentStorage: true,
|
||||
};
|
@ -11,7 +11,9 @@ export const environment = {
|
||||
server: {
|
||||
karso: `${location.origin}/karso/api`,
|
||||
},
|
||||
// set to undefined sso* in case of internal authentification model
|
||||
edgeMode: false,
|
||||
// set to undefined sso* in case of internal authentication model
|
||||
ssoSite: undefined,
|
||||
ssoSignIn: undefined,
|
||||
ssoSignOut: undefined,
|
||||
ssoSignUp: undefined,
|
||||
|
@ -11,7 +11,9 @@ export const environment = {
|
||||
server: {
|
||||
karso: 'http://localhost:15080/karso/api',
|
||||
},
|
||||
// set to undefined sso* in case of internal authentification model
|
||||
edgeMode: false,
|
||||
// set to undefined sso* in case of internal authentication model
|
||||
ssoSite: undefined,
|
||||
ssoSignIn: undefined,
|
||||
ssoSignOut: undefined,
|
||||
ssoSignUp: undefined,
|
||||
|
@ -5,5 +5,9 @@
|
||||
"baseUrl": "./",
|
||||
"types": []
|
||||
},
|
||||
"exclude": ["test.ts", "**/*.spec.ts"]
|
||||
"exclude": [
|
||||
"test.ts",
|
||||
"**/*.spec.ts",
|
||||
"app-root/**"
|
||||
]
|
||||
}
|
13
front/src/tsconfig.app-root.json
Normal file
13
front/src/tsconfig.app-root.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"baseUrl": "./",
|
||||
"types": []
|
||||
},
|
||||
"exclude": [
|
||||
"test.ts",
|
||||
"**/*.spec.ts",
|
||||
"app-edge/**"
|
||||
]
|
||||
}
|
@ -10,13 +10,28 @@
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es2018",
|
||||
"typeRoots": ["node_modules/@types"],
|
||||
"lib": ["es2018", "dom"],
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
],
|
||||
"module": "es2020",
|
||||
"baseUrl": "./src/",
|
||||
"paths": {
|
||||
"@app/*": ["./src/app/"],
|
||||
"@common/*": ["./src/common/"]
|
||||
"@app-base/*": [
|
||||
"./src/base/"
|
||||
],
|
||||
"@app-root/*": [
|
||||
"./src/app-root/"
|
||||
],
|
||||
"@app-edge/*": [
|
||||
"./src/app-edge/"
|
||||
],
|
||||
"@common/*": [
|
||||
"./src/common/"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +1,66 @@
|
||||
{
|
||||
"rulesDirectory": ["node_modules/codelyzer"],
|
||||
"rules": {
|
||||
"arrow-return-shorthand": true,
|
||||
"callable-types": true,
|
||||
"class-name": true,
|
||||
"comment-format": [true, "check-space"],
|
||||
"comment-format": [
|
||||
true,
|
||||
"check-space"
|
||||
],
|
||||
"curly": true,
|
||||
"deprecation": {
|
||||
"severity": "warn"
|
||||
},
|
||||
"eofline": true,
|
||||
"forin": true,
|
||||
"import-blacklist": [true, "rxjs/Rx"],
|
||||
"import-blacklist": [
|
||||
true,
|
||||
"rxjs/Rx"
|
||||
],
|
||||
"import-spacing": true,
|
||||
"indent": [true, "spaces"],
|
||||
"indent": [
|
||||
true,
|
||||
"tabs"
|
||||
],
|
||||
"interface-over-type-literal": true,
|
||||
"label-position": true,
|
||||
"max-line-length": [true, 140],
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": ["static-field", "instance-field", "static-method", "instance-method"]
|
||||
"order": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-arg": true,
|
||||
"no-bitwise": true,
|
||||
"no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-construct": true,
|
||||
"no-debugger": true,
|
||||
"no-duplicate-super": true,
|
||||
"no-empty": false,
|
||||
"no-empty-interface": true,
|
||||
"no-eval": true,
|
||||
"no-inferrable-types": [true, "ignore-params"],
|
||||
"no-inferrable-types": [
|
||||
true,
|
||||
"ignore-params",
|
||||
"ignore-properties"
|
||||
],
|
||||
"no-misused-new": true,
|
||||
"no-non-null-assertion": true,
|
||||
"no-shadowed-variable": true,
|
||||
@ -45,12 +72,27 @@
|
||||
"no-unused-expression": true,
|
||||
"no-var-keyword": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"],
|
||||
"one-line": [
|
||||
true,
|
||||
"check-open-brace",
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-whitespace"
|
||||
],
|
||||
"prefer-const": true,
|
||||
"quotemark": [true, "single"],
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [true, "always"],
|
||||
"triple-equals": [true, "allow-null-check"],
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": [
|
||||
true,
|
||||
"allow-null-check"
|
||||
],
|
||||
"typedef-whitespace": [
|
||||
true,
|
||||
{
|
||||
@ -63,9 +105,26 @@
|
||||
],
|
||||
"unified-signatures": true,
|
||||
"variable-name": false,
|
||||
"whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"],
|
||||
"directive-selector": [true, "attribute", "app", "camelCase"],
|
||||
"component-selector": [true, "element", "app", "kebab-case"],
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"
|
||||
],
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"app",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"app",
|
||||
"kebab-case"
|
||||
],
|
||||
"no-output-on-prefix": true,
|
||||
"no-inputs-metadata-property": true,
|
||||
"no-outputs-metadata-property": true,
|
||||
|
@ -24,7 +24,7 @@ CREATE USER 'karso'@'%' IDENTIFIED BY 'base_db_password';
|
||||
GRANT ALL PRIVILEGES ON `karso`.* TO 'karso'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
> **_Note_** the base_db_password with the production password. this one is for development environment
|
||||
> **_Note_** the `base_db_password` with the production password. this one is for development environment
|
||||
|
||||
|
||||
To start the service
|
||||
|
Loading…
Reference in New Issue
Block a user