user accout

This commit is contained in:
MaxKey 2022-05-03 11:23:52 +08:00
parent 95231504bb
commit 3e080d568f
49 changed files with 487 additions and 788 deletions

View File

@ -19,13 +19,9 @@ package org.maxkey.web.contorller;
import com.google.code.kaptcha.Producer; import com.google.code.kaptcha.Producer;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import javax.imageio.ImageIO;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.maxkey.authn.jwt.AuthTokenService; import org.maxkey.authn.jwt.AuthTokenService;
import org.maxkey.crypto.Base64Utils;
import org.maxkey.entity.Message; import org.maxkey.entity.Message;
import org.maxkey.persistence.MomentaryService; import org.maxkey.persistence.MomentaryService;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -94,16 +90,10 @@ public class ImageCaptchaEndpoint {
momentaryService.put("", kaptchaKey, kaptchaValue); momentaryService.put("", kaptchaKey, kaptchaValue);
// create the image with the text // create the image with the text
BufferedImage bufferedImage = captchaProducer.createImage(kaptchaText); BufferedImage bufferedImage = captchaProducer.createImage(kaptchaText);
// write the data out String b64Image = Base64Utils.encodeImage(bufferedImage);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", stream);
String b64Image = "data:image/png;base64," +
Base64.getEncoder().encodeToString(stream.toByteArray());
_logger.trace("b64Image {}" , b64Image); _logger.trace("b64Image {}" , b64Image);
stream.close();
return new Message<ImageCaptcha>( return new Message<ImageCaptcha>(
new ImageCaptcha(state,b64Image) new ImageCaptcha(state,b64Image)
).buildResponse(); ).buildResponse();

View File

@ -17,9 +17,14 @@
package org.maxkey.crypto; package org.maxkey.crypto;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import javax.imageio.ImageIO;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
/** /**
@ -56,6 +61,25 @@ public final class Base64Utils {
return decoderBase64(cipher); return decoderBase64(cipher);
} }
public static String encodeImage(BufferedImage bufferedImage) {
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", stream);
String b64Image = "data:image/png;base64," +
java.util.Base64.getEncoder().encodeToString(stream.toByteArray());
stream.close();
return b64Image;
}catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static String encodeImage(byte[] byteImage) {
return "data:image/png;base64," +
java.util.Base64.getEncoder().encodeToString(byteImage);
}
/** /**
* encode file to base64 Code String. * encode file to base64 Code String.
* *

View File

@ -18,7 +18,6 @@
package org.maxkey.entity; package org.maxkey.entity;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -29,6 +28,7 @@ import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import org.apache.mybatis.jpa.persistence.JpaBaseEntity; import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
import org.maxkey.crypto.Base64Utils;
import org.maxkey.util.StringUtils; import org.maxkey.util.StringUtils;
/** /**
@ -421,8 +421,7 @@ public class UserInfo extends JpaBaseEntity {
public void transPictureBase64() { public void transPictureBase64() {
if(picture != null) { if(picture != null) {
this.pictureBase64 = "data:image/png;base64," + this.pictureBase64 = Base64Utils.encodeImage(picture);
Base64.getEncoder().encodeToString(picture);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,7 +18,6 @@
package org.maxkey.entity.apps; package org.maxkey.entity.apps;
import java.io.Serializable; import java.io.Serializable;
import java.util.Base64;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@ -29,6 +28,7 @@ import javax.persistence.Table;
import org.apache.mybatis.jpa.persistence.JpaBaseEntity; import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
import org.maxkey.constants.ConstsBoolean; import org.maxkey.constants.ConstsBoolean;
import org.maxkey.crypto.Base64Utils;
@Entity @Entity
@Table(name = "MXK_APPS") @Table(name = "MXK_APPS")
@ -292,8 +292,7 @@ public class Apps extends JpaBaseEntity implements Serializable {
public void transIconBase64() { public void transIconBase64() {
if(icon !=null) { if(icon !=null) {
this.iconBase64 = "data:image/png;base64," + this.iconBase64 = Base64Utils.encodeImage(icon);
Base64.getEncoder().encodeToString(icon);
} }
} }

View File

@ -1,121 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.constants.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* AbstractImageEndpoint Producer Image .
* @author Crystal.Sea
*
*/
public class AbstractImageEndpoint {
private static final Logger _logger = LoggerFactory.getLogger(AbstractImageEndpoint.class);
@Autowired
@Qualifier("applicationConfig")
protected ApplicationConfig applicationConfig;
/**
* producerImage.
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param bufferedImage BufferedImage
* @throws IOException error
*/
public static void producerImage(HttpServletRequest request,
HttpServletResponse response,
BufferedImage bufferedImage) throws IOException {
// Set to expire far in the past.
response.setDateHeader("Expires", 0);
// Set standard HTTP/1.1 no-cache headers.
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
// Set IE extended HTTP/1.1 no-cache headers (use addHeader).
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
// Set standard HTTP/1.0 no-cache header.
response.setHeader("Pragma", "no-cache");
// return a jpeg/gif
response.setContentType(ContentType.IMAGE_GIF);
_logger.trace("create the image");
// create the image
if (bufferedImage != null) {
ServletOutputStream out = response.getOutputStream();
// write the data out
ImageIO.write(bufferedImage, "gif", out);
try {
out.flush();
} finally {
out.close();
}
}
}
/**
* byte2BufferedImage.
* @param imageByte bytes
* @return
*/
public static BufferedImage byte2BufferedImage(byte[] imageByte) {
try {
InputStream in = new ByteArrayInputStream(imageByte);
BufferedImage bufferedImage = ImageIO.read(in);
return bufferedImage;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* bufferedImage2Byte.
* @param bufferedImage BufferedImage
* @return
*/
public static byte[] bufferedImage2Byte(BufferedImage bufferedImage) {
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "gif", byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void setApplicationConfig(ApplicationConfig applicationConfig) {
this.applicationConfig = applicationConfig;
}
}

View File

@ -1,57 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.image;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* ImageEndpoint Producer Image and captcha.
* @author Crystal.Sea
*
*/
@Controller
public class ImageEndpoint extends AbstractImageEndpoint {
private static final Logger _logger = LoggerFactory.getLogger(ImageEndpoint.class);
/**
* Session Image Producer.
*
* @param request HttpServletRequest
* @param response HttpServletResponse
*/
@RequestMapping("/image/{id}")
public void imageHandleRequest(HttpServletRequest request, HttpServletResponse response,
@PathVariable("id") String id) {
try {
// get session image bytes
byte[] image = (byte[]) request.getSession().getAttribute(id);
producerImage(request,response,byte2BufferedImage(image));
} catch (Exception e) {
_logger.error("captcha Producer Error " + e.getMessage());
}
}
}

View File

@ -1,57 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.tag;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* 获取当前页面地址标签
* <@currUrl/>
* @author Crystal.Sea
*
*/
@FreemarkerTag("currUrl")
public class CurrUrlTagDirective implements TemplateDirectiveModel {
@Autowired
private HttpServletRequest request;
@Override
@SuppressWarnings("rawtypes")
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
//String url = params.get(URL).toString();
String currUrl=request.getRequestURI();
env.getOut().append(currUrl);
}
}

View File

@ -1,65 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.tag;
import java.io.IOException;
import java.util.Map;
import org.maxkey.util.DateUtils;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* 获取应用上下文标签
* <@date format="" value=""></@date>
* @author Crystal.Sea
*
*/
@FreemarkerTag("date")
public class DateTagDirective implements TemplateDirectiveModel {
@Override
@SuppressWarnings("rawtypes")
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
String dateValue = params.get("value").toString();
String format = params.get("format").toString();
String dateString="";
if(dateValue==null) {
if(format==null) {
dateString=DateUtils.getCurrentDateAsString(DateUtils.FORMAT_DATE_YYYY_MM_DD);
}else {
dateString=DateUtils.getCurrentDateAsString(format);
}
}else {
if(format==null) {
dateString=DateUtils.format(DateUtils.tryParse(dateValue),DateUtils.FORMAT_DATE_YYYY_MM_DD);
}else {
dateString=DateUtils.format(DateUtils.tryParse(dateValue),format);
}
}
env.getOut().append(dateString);
}
}

View File

@ -1,48 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.tag;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* 获取应用上下文标签
* <@genId/>
* @author Crystal.Sea
*
*/
@FreemarkerTag("genId")
public class GenIdTagDirective implements TemplateDirectiveModel {
@Override
@SuppressWarnings("rawtypes")
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
env.getOut().append(UUID.randomUUID().toString().toLowerCase());
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.tag;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* 获取应用上下文标签
* <@parameter/>
* @author Crystal.Sea
*
*/
@FreemarkerTag("parameter")
public class ParameterTagDirective implements TemplateDirectiveModel {
@Autowired
private HttpServletRequest request;
private String name;
@Override
@SuppressWarnings("rawtypes")
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
name=params.get("name").toString();
env.getOut().append(request.getParameter(name));
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.tag;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* 获取应用上下文标签
* <@pathVar/>
* @author Crystal.Sea
*
*/
@FreemarkerTag("pathVar")
public class PathVarTagDirective implements TemplateDirectiveModel {
@Autowired
private HttpServletRequest request;
private int index;
String pathVariable;
@Override
@SuppressWarnings("rawtypes")
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
index=Integer.parseInt(params.get("index").toString());
String[] pathVariables=request.getAttribute(org.springframework.web.util.WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE).toString().split("/");
if(pathVariables==null){
pathVariables=request.getRequestURI().split("/");
}
if(index==0){
pathVariable=pathVariables[pathVariables.length-1];
}else{
pathVariable=pathVariables[index+1];
}
env.getOut().append(request.getParameter(pathVariable));
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.tag;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* 获取应用上下文标签
* <@locale/>
* @author Crystal.Sea
*
*/
@FreemarkerTag("redirect")
public class RedirectTagDirective implements TemplateDirectiveModel {
@Autowired
private HttpServletRequest request;
private HttpServletResponse response;
private String basePath = null;
@Override
@SuppressWarnings("rawtypes")
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
String location=params.get("url").toString();
basePath = request.getScheme()+"://"+request.getServerName();
int port=request.getServerPort();
//Ignore 443 or 80 port
if((port==443 && request.getScheme().equalsIgnoreCase("https"))
||(port==80 && request.getScheme().equalsIgnoreCase("http"))){
}else{
basePath += ":"+port;
}
basePath += request.getContextPath()+"";
response.sendRedirect(basePath+"/"+location);
}
}

View File

@ -1,86 +0,0 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.tag;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Map;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* 静态变量读取
* <@static/>
* @author Crystal.Sea
*
*/
@FreemarkerTag("static")
public class StaticTagDirective implements TemplateDirectiveModel {
@Override
@SuppressWarnings("rawtypes")
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
// 获取字符串变量
String[] c = params.get("name").toString().trim().split("@");
StringBuffer sb = new StringBuffer();
try {
if(null == c || c.length < 2) {
throw new TemplateException("至少应该包含一个@符。", env);
}
Class<?> clazz = null;
for(int i=0;i<c.length;i++) {
sb.append(c[i]).append("@");
if(i == 0) {
clazz = Class.forName(c[i]);
} else if(i != c.length - 1) {
Class<?>[] clazzs = clazz.getDeclaredClasses();
boolean flag = false;
for(Class<?> clz : clazzs) {
if(clz.getSimpleName().equals(c[i])) {
clazz = clz;
flag = true;
break;
}
}
if(!flag) {
throw new TemplateException("内部类 " + sb.substring(0, sb.length() - 1) + " 未找到。", env);
}
} else {
Field sp = clazz.getDeclaredField(c[i]);
env.getOut().write(sp.get(clazz).toString());
}
}
} catch (ClassNotFoundException e) {
throw new TemplateException("" + sb.substring(0, sb.length() - 1) + " 未找到。", e.getCause(), env);
} catch (NoSuchFieldException e) {
throw new TemplateException("属性 " + sb.substring(0, sb.length() - 1) + " 未找到。", e.getCause(), env);
} catch (IllegalAccessException e) {
throw new TemplateException("没权限访问 " + sb.substring(0, sb.length() - 1) + " 属性。", e.getCause(), env);
}
}
}

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* eslint-disable import/order */ /* eslint-disable import/order */
/* eslint-disable import/no-duplicates */ /* eslint-disable import/no-duplicates */

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
@ -66,7 +65,8 @@ export class StartupService {
// 用户信息:包括姓名、头像、邮箱地址 // 用户信息:包括姓名、头像、邮箱地址
//this.settingService.setUser(appData.user); //this.settingService.setUser(appData.user);
// ACL设置权限为全量 // ACL设置权限为全量
this.aclService.setFull(true); this.aclService.setFull(false);
// 初始化菜单 // 初始化菜单
this.menuService.add(appData.menu); this.menuService.add(appData.menu);
// 设置页面标题的后缀 // 设置页面标题的后缀

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* eslint-disable import/order */ /* eslint-disable import/order */
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';

View File

@ -1,26 +1,27 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Component } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { ACLService } from '@delon/acl';
import { SettingsService, User } from '@delon/theme'; import { SettingsService, User } from '@delon/theme';
import { environment } from '@env/environment'; import { environment } from '@env/environment';
import { CONSTS } from 'src/app/shared/consts'; import { CONSTS } from 'src/app/shared/consts';
import { AuthnService } from '../../service/authn.service';
import { LayoutDefaultOptions } from '../../theme/layout-default'; import { LayoutDefaultOptions } from '../../theme/layout-default';
@Component({ @Component({

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Component, Inject, OnInit } from '@angular/core'; import { Component, Inject, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';

View File

@ -0,0 +1,42 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Inject, Optional, Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ReuseTabService } from '@delon/abc/reuse-tab';
import { SettingsService } from '@delon/theme';
import { environment } from '@env/environment';
import { AuthnService } from '../../service/authn.service';
import { SocialsProviderService } from '../../service/socials-provider.service';
@Component({
selector: 'app-callback',
template: ``
})
export class AuthzMgtComponent implements OnInit {
constructor() { }
ngOnInit(): void {
let baseUrl = '';
if (environment.api.baseUrl.endsWith('/')) {
baseUrl = environment.api.baseUrl.substring(0, environment.api.baseUrl.length - 1);
} else {
baseUrl = environment.api.baseUrl;
}
window.location.href = `${baseUrl}/authz/jwt/maxkey_mgt`;
}
}

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
@ -21,6 +20,7 @@ import { RouterModule, Routes } from '@angular/router';
import { SharedModule } from '@shared'; import { SharedModule } from '@shared';
import { LayoutBlankComponent } from '../../layout/blank/blank.component'; import { LayoutBlankComponent } from '../../layout/blank/blank.component';
import { AuthzMgtComponent } from './authz-mgt.component';
import { CredentialComponent } from './credential/credential.component'; import { CredentialComponent } from './credential/credential.component';
import { Oauth2ApproveComponent } from './oauth2-approve/oauth2-approve.component'; import { Oauth2ApproveComponent } from './oauth2-approve/oauth2-approve.component';
const routes: Routes = [ const routes: Routes = [
@ -43,6 +43,11 @@ const routes: Routes = [
path: 'oauth2approve', path: 'oauth2approve',
component: Oauth2ApproveComponent, component: Oauth2ApproveComponent,
data: { title: 'credential', titleI18n: 'app.login.login' } data: { title: 'credential', titleI18n: 'app.login.login' }
},
{
path: 'mgt',
component: AuthzMgtComponent,
data: { title: 'mgt', titleI18n: 'app.login.login' }
} }
] ]
} }

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, Inject, OnDestroy, Optional } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, Inject, OnDestroy, Optional } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
@ -70,7 +69,9 @@ export class CredentialComponent implements OnInit {
if (res.code == 0) { if (res.code == 0) {
this.form.model.init(res.data); this.form.model.init(res.data);
this.msg.success(`提交成功`); this.msg.success(`提交成功`);
window.location.href = `${environment.api.baseUrl}${this.redirect_uri}`; if (this.redirect_uri) {
window.location.href = `${environment.api.baseUrl}${this.redirect_uri}`;
}
} else { } else {
this.msg.success(`提交失败`); this.msg.success(`提交失败`);
} }

View File

@ -0,0 +1,106 @@
<form nz-form [formGroup]="formGroup" (ngSubmit)="onSubmit()" se-container="1">
<nz-form-item style="display: none">
<nz-form-label [nzMd]="6" nzFor="id">id</nz-form-label>
<nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
<input [(ngModel)]="form.model.id" [ngModelOptions]="{ standalone: true }" nz-input name="id" id="id" value="id" />
</nz-form-control>
</nz-form-item>
<nz-form-item style="width: 100%">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="displayName">{{ 'mxk.password.displayName' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not displayName!">
<input
nz-input
disabled="true"
[(ngModel)]="form.model.displayName"
[ngModelOptions]="{ standalone: true }"
name="displayName"
id="displayName"
value="0"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item style="width: 100%">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="username">{{ 'mxk.accounts.username' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid username!">
<input
nz-input
disabled="true"
[(ngModel)]="form.model.username"
[ngModelOptions]="{ standalone: true }"
name="username"
id="username"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item style="width: 100%">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="appName">{{ 'mxk.accounts.appName' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid appName!">
<input
nz-input
disabled="true"
[(ngModel)]="form.model.appName"
[ngModelOptions]="{ standalone: true }"
name="appName"
id="appName"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item style="width: 100%">
<nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="relatedUsername">{{ 'mxk.accounts.relatedUsername' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid relatedUsername!">
<input
nz-input
[(ngModel)]="form.model.relatedUsername"
[ngModelOptions]="{ standalone: true }"
name="relatedUsername"
id="relatedUsername"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item style="width: 100%">
<nz-form-label nzRequired [nzSm]="6" [nzXs]="24" nzFor="relatedPassword">{{ 'mxk.accounts.relatedPassword' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid relatedPassword!">
<nz-input-group [nzSuffix]="suffixPasswordTemplate" style="width: 100%">
<input
[type]="passwordVisible ? 'text' : 'password'"
nz-input
placeholder="new password"
[(ngModel)]="form.model.relatedPassword"
[ngModelOptions]="{ standalone: true }"
name="relatedPassword"
id="relatedPassword"
/>
</nz-input-group>
<ng-template #suffixPasswordTemplate>
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item style="width: 100%">
<nz-form-label nzRequired [nzSm]="6" [nzXs]="24" nzFor="confirmPassword">{{ 'mxk.password.confirmPassword' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid confirmPassword!">
<nz-input-group [nzSuffix]="suffixConfirmPasswordTemplate" style="width: 100%">
<input
[type]="confirmPasswordVisible ? 'text' : 'password'"
nz-input
placeholder="confirm password"
[(ngModel)]="form.model.confirmPassword"
[ngModelOptions]="{ standalone: true }"
name="confirmPassword"
id="confirmPassword"
/>
</nz-input-group>
<ng-template #suffixConfirmPasswordTemplate>
<i
nz-icon
[nzType]="confirmPasswordVisible ? 'eye-invisible' : 'eye'"
(click)="confirmPasswordVisible = !confirmPasswordVisible"
></i>
</ng-template>
</nz-form-control>
</nz-form-item>
</form>
<div *nzModalFooter>
<button nz-button nzType="default" (click)="onClose($event)">{{ 'mxk.text.close' | i18n }}</button>
<button nz-button nzType="primary" (click)="onSubmit()">{{ 'mxk.text.submit' | i18n }}</button>
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AccoutsComponent } from './accouts.component';
describe('AccoutsComponent', () => {
let component: AccoutsComponent;
let fixture: ComponentFixture<AccoutsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AccoutsComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AccoutsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,79 @@
import { Component, ChangeDetectorRef, OnInit, Input } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { environment } from '@env/environment';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { Accounts } from '../../../entity/Accounts';
import { AccountsService } from '../../../service/accounts.service';
@Component({
selector: 'app-accouts',
templateUrl: './accouts.component.html',
styleUrls: ['./accouts.component.less']
})
export class AccoutsComponent implements OnInit {
@Input() appId?: String;
form: {
submitting: boolean;
model: Accounts;
} = {
submitting: false,
model: new Accounts()
};
redirect_uri: string = '';
formGroup: FormGroup = new FormGroup({});
confirmPasswordVisible = false;
passwordVisible = false;
constructor(
fb: FormBuilder,
private router: Router,
private route: ActivatedRoute,
private modalRef: NzModalRef,
private accountsService: AccountsService,
private msg: NzMessageService,
private cdr: ChangeDetectorRef
) { }
ngOnInit(): void {
if (this.appId) {
this.accountsService.get(this.appId).subscribe(res => {
console.log(res.data);
this.form.model.init(res.data);
this.cdr.detectChanges();
});
}
}
onClose(e: MouseEvent): void {
e.preventDefault();
this.modalRef.destroy({ refresh: false });
}
onSubmit(): void {
this.form.submitting = true;
this.form.model.trans();
//if (this.formGroup.valid) {
this.accountsService.update(this.form.model).subscribe(res => {
if (res.code == 0) {
this.form.model.init(res.data);
this.msg.success(`提交成功`);
if (this.redirect_uri) {
window.location.href = `${environment.api.baseUrl}${this.redirect_uri}`;
}
} else {
this.msg.success(`提交失败`);
}
});
// } else {
// this.formGroup.updateValueAndValidity({ onlySelf: true });
// this.msg.success(`提交失败`);
//}
this.form.submitting = false;
this.cdr.detectChanges();
}
}

View File

@ -33,6 +33,7 @@ import { ProfileComponent } from './profile/profile.component';
import { SocialsAssociateComponent } from './socials-associate/socials-associate.component'; import { SocialsAssociateComponent } from './socials-associate/socials-associate.component';
import { SocialsProviderComponent } from './socials-provider/socials-provider.component'; import { SocialsProviderComponent } from './socials-provider/socials-provider.component';
import { TimebasedComponent } from './timebased/timebased.component'; import { TimebasedComponent } from './timebased/timebased.component';
import { AccoutsComponent } from './accouts/accouts.component';
const routes: Routes = [ const routes: Routes = [
{ {
@ -62,7 +63,8 @@ const COMPONENTS = [ProfileComponent];
TimebasedComponent, TimebasedComponent,
SocialsAssociateComponent, SocialsAssociateComponent,
PasswordComponent, PasswordComponent,
ProfileComponent ProfileComponent,
AccoutsComponent
], ],
imports: [SharedModule, CommonModule, RouterModule.forChild(routes)], imports: [SharedModule, CommonModule, RouterModule.forChild(routes)],
exports: [RouterModule] exports: [RouterModule]

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CountDownModule } from '@delon/abc/count-down'; import { CountDownModule } from '@delon/abc/count-down';

View File

@ -34,7 +34,7 @@
</ng-template>--> </ng-template>-->
<nz-card-meta [nzTitle]="item.title" [nzAvatar]="nzAvatar" *ngIf="item.protocol == 'Form_Based'"> <nz-card-meta [nzTitle]="item.title" [nzAvatar]="nzAvatar" *ngIf="item.protocol == 'Form_Based'">
<ng-template #nzAvatar> <ng-template #nzAvatar>
<i nz-icon nzType="setting" nzTheme="outline"></i> <i nz-icon nzType="user-add" nzTheme="outline" (click)="setAccount(item.id)"> </i>
<!--<nz-avatar nzSize="small" [nzSrc]="item.iconBase64"></nz-avatar>--> <!--<nz-avatar nzSize="small" [nzSrc]="item.iconBase64"></nz-avatar>-->
</ng-template> </ng-template>
</nz-card-meta> </nz-card-meta>

View File

@ -1,30 +1,36 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Platform } from '@angular/cdk/platform'; import { Platform } from '@angular/cdk/platform';
import { DOCUMENT } from '@angular/common'; import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit, Renderer2 } from '@angular/core'; import { ChangeDetectionStrategy, ViewContainerRef, ChangeDetectorRef, Component, Inject, OnInit, Renderer2 } from '@angular/core';
import type { Chart } from '@antv/g2'; import type { Chart } from '@antv/g2';
import { OnboardingService } from '@delon/abc/onboarding'; import { OnboardingService } from '@delon/abc/onboarding';
import { ACLService } from '@delon/acl';
import { environment } from '@env/environment'; import { environment } from '@env/environment';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { NzSafeAny } from 'ng-zorro-antd/core/types'; import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { CONSTS } from 'src/app/shared/consts';
import { AppListService } from '../../../service/appList.service'; import { AppListService } from '../../../service/appList.service';
import { AuthnService } from '../../../service/authn.service';
import { AccoutsComponent } from '../../config/accouts/accouts.component';
import { Console } from 'console';
@Component({ @Component({
selector: 'app-home', selector: 'app-home',
@ -47,6 +53,8 @@ export class HomeComponent implements OnInit {
baseUrl: String = ''; baseUrl: String = '';
constructor( constructor(
private modal: NzModalService,
private viewContainerRef: ViewContainerRef,
private appListService: AppListService, private appListService: AppListService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private obSrv: OnboardingService, private obSrv: OnboardingService,
@ -77,15 +85,26 @@ export class HomeComponent implements OnInit {
} }
window.open(`${this.baseUrl}/authz/${appId}`); window.open(`${this.baseUrl}/authz/${appId}`);
} }
setAccount(appId: string): void {
const modal = this.modal.create({
nzContent: AccoutsComponent,
nzViewContainerRef: this.viewContainerRef,
nzComponentParams: {
appId: appId
},
nzWidth: 550
//nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))
});
}
ngOnInit(): void { ngOnInit(): void {
if (environment.api.baseUrl.endsWith('/')) { if (environment.api.baseUrl.endsWith('/')) {
this.baseUrl = environment.api.baseUrl.substring(0, environment.api.baseUrl.length - 1); this.baseUrl = environment.api.baseUrl.substring(0, environment.api.baseUrl.length - 1);
} else { } else {
this.baseUrl = environment.api.baseUrl; this.baseUrl = environment.api.baseUrl;
} }
this.appListService.appList().subscribe(res => { this.appListService.appList().subscribe(res => {
console.log(res.data); //console.log(res.data);
this.appList = res.data; this.appList = res.data;
this.cdr.detectChanges(); this.cdr.detectChanges();
}); });

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { ACLService } from '@delon/acl'; import { ACLService } from '@delon/acl';
@ -36,7 +35,7 @@ export class ACLComponent {
return this.aclSrv.data; return this.aclSrv.data;
} }
constructor(private aclSrv: ACLService, private menuSrv: MenuService) {} constructor(private aclSrv: ACLService, private menuSrv: MenuService) { }
private reMenu(): void { private reMenu(): void {
this.menuSrv.resume(); this.menuSrv.resume();

View File

@ -1,26 +1,25 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Inject, Optional, Component, OnInit } from '@angular/core'; import { Inject, Optional, Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { ReuseTabService } from '@delon/abc/reuse-tab'; import { ReuseTabService } from '@delon/abc/reuse-tab';
import { SettingsService } from '@delon/theme'; import { SettingsService } from '@delon/theme';
import { AuthenticationService } from '../../service/authentication.service'; import { AuthnService } from '../../service/authn.service';
import { SocialsProviderService } from '../../service/socials-provider.service'; import { SocialsProviderService } from '../../service/socials-provider.service';
@Component({ @Component({
@ -34,7 +33,7 @@ export class CallbackComponent implements OnInit {
private router: Router, private router: Router,
private socialsProviderService: SocialsProviderService, private socialsProviderService: SocialsProviderService,
private settingsService: SettingsService, private settingsService: SettingsService,
private authenticationService: AuthenticationService, private authnService: AuthnService,
@Optional() @Optional()
@Inject(ReuseTabService) @Inject(ReuseTabService)
private reuseTabService: ReuseTabService, private reuseTabService: ReuseTabService,
@ -49,9 +48,9 @@ export class CallbackComponent implements OnInit {
// 清空路由复用信息 // 清空路由复用信息
this.reuseTabService.clear(); this.reuseTabService.clear();
// 设置用户Token信息 // 设置用户Token信息
this.authenticationService.auth(res.data); this.authnService.auth(res.data);
} }
this.authenticationService.navigate({}); this.authnService.navigate({});
}); });
} else { } else {
this.socialsProviderService.bind(this.provider, this.route.snapshot.queryParams).subscribe(res => { this.socialsProviderService.bind(this.provider, this.route.snapshot.queryParams).subscribe(res => {

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit, OnDestroy, AfterViewInit, Optional } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit, OnDestroy, AfterViewInit, Optional } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
@ -27,7 +26,7 @@ import { NzMessageService } from 'ng-zorro-antd/message';
import { NzTabChangeEvent } from 'ng-zorro-antd/tabs'; import { NzTabChangeEvent } from 'ng-zorro-antd/tabs';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
import { AuthenticationService } from '../../../service/authentication.service'; import { AuthnService } from '../../../service/authn.service';
import { ImageCaptchaService } from '../../../service/image-captcha.service'; import { ImageCaptchaService } from '../../../service/image-captcha.service';
import { SocialsProviderService } from '../../../service/socials-provider.service'; import { SocialsProviderService } from '../../../service/socials-provider.service';
import { CONSTS } from '../../../shared/consts'; import { CONSTS } from '../../../shared/consts';
@ -65,7 +64,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
fb: FormBuilder, fb: FormBuilder,
private router: Router, private router: Router,
private settingsService: SettingsService, private settingsService: SettingsService,
private authenticationService: AuthenticationService, private authnService: AuthnService,
private socialsProviderService: SocialsProviderService, private socialsProviderService: SocialsProviderService,
private imageCaptchaService: ImageCaptchaService, private imageCaptchaService: ImageCaptchaService,
@Optional() @Optional()
@ -88,7 +87,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
//set redirect_uri , is BASE64URL //set redirect_uri , is BASE64URL
if (this.route.snapshot.queryParams[CONSTS.REDIRECT_URI]) { if (this.route.snapshot.queryParams[CONSTS.REDIRECT_URI]) {
this.authenticationService.setRedirectUri(this.route.snapshot.queryParams[CONSTS.REDIRECT_URI]); this.authnService.setRedirectUri(this.route.snapshot.queryParams[CONSTS.REDIRECT_URI]);
} }
//congress login //congress login
@ -97,8 +96,8 @@ export class UserLoginComponent implements OnInit, OnDestroy {
} }
//init socials,state //init socials,state
this.authenticationService.clear(); this.authnService.clear();
this.authenticationService this.authnService
.get({ remember_me: localStorage.getItem(CONSTS.REMEMBER) }) .get({ remember_me: localStorage.getItem(CONSTS.REMEMBER) })
.pipe( .pipe(
finalize(() => { finalize(() => {
@ -118,8 +117,8 @@ export class UserLoginComponent implements OnInit, OnDestroy {
// 清空路由复用信息 // 清空路由复用信息
this.reuseTabService.clear(); this.reuseTabService.clear();
// 设置用户Token信息 // 设置用户Token信息
this.authenticationService.auth(res.data); this.authnService.auth(res.data);
this.authenticationService.navigate({}); this.authnService.navigate({});
} else { } else {
this.socials = res.data.socials; this.socials = res.data.socials;
this.state = res.data.state; this.state = res.data.state;
@ -136,7 +135,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
} }
congressLogin(congress: string) { congressLogin(congress: string) {
this.authenticationService this.authnService
.congress({ .congress({
congress: congress congress: congress
}) })
@ -154,8 +153,8 @@ export class UserLoginComponent implements OnInit, OnDestroy {
// 清空路由复用信息 // 清空路由复用信息
this.reuseTabService.clear(); this.reuseTabService.clear();
// 设置用户Token信息 // 设置用户Token信息
this.authenticationService.auth(res.data); this.authnService.auth(res.data);
this.authenticationService.navigate({}); this.authnService.navigate({});
} }
}); });
} }
@ -199,7 +198,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
this.mobile.updateValueAndValidity({ onlySelf: true }); this.mobile.updateValueAndValidity({ onlySelf: true });
return; return;
} }
this.authenticationService.produceOtp({ mobile: this.mobile.value }).subscribe(res => { this.authnService.produceOtp({ mobile: this.mobile.value }).subscribe(res => {
if (res.code !== 0) { if (res.code !== 0) {
this.msg.success(`发送失败`); this.msg.success(`发送失败`);
} }
@ -242,7 +241,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
this.loading = true; this.loading = true;
this.cdr.detectChanges(); this.cdr.detectChanges();
this.authenticationService this.authnService
.login({ .login({
authType: this.loginType, authType: this.loginType,
state: this.state, state: this.state,
@ -271,8 +270,8 @@ export class UserLoginComponent implements OnInit, OnDestroy {
// 清空路由复用信息 // 清空路由复用信息
this.reuseTabService.clear(); this.reuseTabService.clear();
// 设置用户Token信息 // 设置用户Token信息
this.authenticationService.auth(res.data); this.authnService.auth(res.data);
this.authenticationService.navigate({}); this.authnService.navigate({});
} }
this.cdr.detectChanges(); this.cdr.detectChanges();
}); });
@ -287,7 +286,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
} }
getQrCode(): void { getQrCode(): void {
this.authenticationService.clearUser(); this.authnService.clearUser();
this.socialsProviderService.scanqrcode(this.socials.qrScan).subscribe(res => { this.socialsProviderService.scanqrcode(this.socials.qrScan).subscribe(res => {
if (res.code === 0) { if (res.code === 0) {
if (this.socials.qrScan === 'workweixin') { if (this.socials.qrScan === 'workweixin') {

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { NgModule, Type } from '@angular/core'; import { NgModule, Type } from '@angular/core';
import { SharedModule } from '@shared'; import { SharedModule } from '@shared';

View File

@ -1,23 +1,23 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Injectable, Inject } from '@angular/core'; import { Injectable, Inject } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { StartupService } from '@core'; import { StartupService } from '@core';
import { ACLService } from '@delon/acl';
import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
import { SettingsService, _HttpClient, User } from '@delon/theme'; import { SettingsService, _HttpClient, User } from '@delon/theme';
import * as CryptoJS from 'crypto-js'; import * as CryptoJS from 'crypto-js';
@ -29,7 +29,7 @@ import { hostname } from 'os';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class AuthenticationService { export class AuthnService {
redirect_uri: string = ''; redirect_uri: string = '';
constructor( constructor(
@ -91,6 +91,7 @@ export class AuthenticationService {
this.cookieService.set(CONSTS.CONGRESS, authJwt.token); this.cookieService.set(CONSTS.CONGRESS, authJwt.token);
this.cookieService.set(CONSTS.ONLINE_TICKET, authJwt.ticket, { domain: subHostName }); this.cookieService.set(CONSTS.ONLINE_TICKET, authJwt.ticket, { domain: subHostName });
if (authJwt.remeberMe) { if (authJwt.remeberMe) {
localStorage.setItem(CONSTS.REMEMBER, authJwt.remeberMe); localStorage.setItem(CONSTS.REMEMBER, authJwt.remeberMe);
} }
@ -99,6 +100,26 @@ export class AuthenticationService {
this.tokenService.get()?.expired; this.tokenService.get()?.expired;
} }
setRoles(aclService: ACLService | null): string[] {
let authorities: string[] = JSON.parse(localStorage.getItem(CONSTS.TOKEN) || '')?.authorities || [];
if (aclService) {
aclService.setRole(authorities);
}
return authorities;
}
hasRole(role: string): boolean {
if (role) {
let authorities: string[] = JSON.parse(localStorage.getItem(CONSTS.TOKEN) || '')?.authorities || [];
for (let i = 0; i < authorities.length; i++) {
if (role == authorities[i]) {
return true;
}
}
}
return false;
}
navigate(authJwt: any) { navigate(authJwt: any) {
// 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响 // 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响
this.startupService.load().subscribe(() => { this.startupService.load().subscribe(() => {

View File

@ -1,24 +1,24 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
export const CONSTS = { export const CONSTS = {
CONGRESS: 'congress', CONGRESS: 'congress',
ONLINE_TICKET: 'online_ticket', ONLINE_TICKET: 'online_ticket',
REDIRECT_URI: 'redirect_uri', REDIRECT_URI: 'redirect_uri',
REMEMBER: 'remember_me', REMEMBER: 'remember_me',
TOKEN: '_token',
VERSION: 'v3.5.0 GA' VERSION: 'v3.5.0 GA'
}; };

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { PageHeaderModule } from '@delon/abc/page-header'; import { PageHeaderModule } from '@delon/abc/page-header';
import { ResultModule } from '@delon/abc/result'; import { ResultModule } from '@delon/abc/result';

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { NzAlertModule } from 'ng-zorro-antd/alert'; import { NzAlertModule } from 'ng-zorro-antd/alert';
import { NzAvatarModule } from 'ng-zorro-antd/avatar'; import { NzAvatarModule } from 'ng-zorro-antd/avatar';

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule, Type } from '@angular/core'; import { NgModule, Type } from '@angular/core';
@ -49,6 +48,7 @@ const DIRECTIVES: Array<Type<any>> = [];
RouterModule, RouterModule,
ReactiveFormsModule, ReactiveFormsModule,
AlainThemeModule.forChild(), AlainThemeModule.forChild(),
DelonACLModule.forRoot(),
DelonACLModule, DelonACLModule,
DelonFormModule, DelonFormModule,
...SHARED_DELON_MODULES, ...SHARED_DELON_MODULES,

View File

@ -2,21 +2,23 @@
<ul nz-menu nzMode="horizontal" nzTheme="dark" style="text-align: center"> <ul nz-menu nzMode="horizontal" nzTheme="dark" style="text-align: center">
<!--一级菜单--> <!--一级菜单-->
<ng-container *ngFor="let mnav of ls"> <ng-container *ngFor="let mnav of ls">
<li nz-menu-item *ngIf="mnav.children.length == 0" style="min-width: 80px"> <li nz-menu-item *ngIf="mnav.children.length == 0 && mnav.disabled == false" style="min-width: 80px">
<a href="#{{ mnav.link }}">{{ mnav.text }}</a> <a *ngIf="mnav.externalLink == ''" href="#{{ mnav.link }}">{{ mnav.text }}</a>
<a *ngIf="mnav.externalLink != ''" href="#{{ mnav.externalLink }}" target="_blank">{{ mnav.text }}</a>
</li> </li>
<li nz-submenu nzTitle="{{ mnav.text }}" *ngIf="mnav.children.length > 0"> <li nz-submenu nzTitle="{{ mnav.text }}" *ngIf="mnav.children.length > 0">
<ul> <ul>
<!--二级菜单--> <!--二级菜单-->
<ng-container *ngFor="let snav of mnav.children"> <ng-container *ngFor="let snav of mnav.children">
<li nz-menu-item *ngIf="snav.children.length == 0"> <li nz-menu-item *ngIf="snav.children.length == 0 && mnav.disabled == false">
<a href="#{{ snav.link }}">{{ snav.text }}</a> <a href="#{{ snav.link }}">{{ snav.text }}</a>
</li> </li>
<li nz-submenu nzTitle="{{ snav.text }}" *ngIf="snav.children.length > 0"> <li nz-submenu nzTitle="{{ snav.text }}" *ngIf="snav.children.length > 0">
<ul> <ul>
<!--三级菜单--> <!--三级菜单-->
<ng-container *ngFor="let tnav of snav.children"> <ng-container *ngFor="let tnav of snav.children">
<li nz-menu-item *ngIf="tnav.children.length == 0"> <li nz-menu-item *ngIf="tnav.children.length == 0 && mnav.disabled == false">
<a href="#{{ tnav.link }}">{{ tnav.text }}</a> <a href="#{{ tnav.link }}">{{ tnav.text }}</a>
</li> </li>
</ng-container> </ng-container>

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Direction, Directionality } from '@angular/cdk/bidi'; import { Direction, Directionality } from '@angular/cdk/bidi';
import { DOCUMENT } from '@angular/common'; import { DOCUMENT } from '@angular/common';
@ -34,6 +33,7 @@ import {
} from '@angular/core'; } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { NavigationEnd, Router } from '@angular/router'; import { NavigationEnd, Router } from '@angular/router';
import { ACLService } from '@delon/acl';
import { Menu, MenuIcon, MenuInner, MenuService, SettingsService } from '@delon/theme'; import { Menu, MenuIcon, MenuInner, MenuService, SettingsService } from '@delon/theme';
import { BooleanInput, InputBoolean, InputNumber, NumberInput, ZoneOutside } from '@delon/util/decorator'; import { BooleanInput, InputBoolean, InputNumber, NumberInput, ZoneOutside } from '@delon/util/decorator';
import { WINDOW } from '@delon/util/token'; import { WINDOW } from '@delon/util/token';
@ -41,6 +41,7 @@ import type { NzSafeAny } from 'ng-zorro-antd/core/types';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators'; import { filter, takeUntil } from 'rxjs/operators';
import { AuthnService } from '../../service/authn.service';
import { LayoutDefaultOptions } from './types'; import { LayoutDefaultOptions } from './types';
export interface Nav extends MenuInner { export interface Nav extends MenuInner {
@ -89,6 +90,8 @@ export class LayoutDefaultNavComponent implements OnInit, OnDestroy {
constructor( constructor(
private menuSrv: MenuService, private menuSrv: MenuService,
private authnService: AuthnService,
private aclService: ACLService,
private settings: SettingsService, private settings: SettingsService,
private router: Router, private router: Router,
private render: Renderer2, private render: Renderer2,
@ -280,6 +283,8 @@ export class LayoutDefaultNavComponent implements OnInit, OnDestroy {
} }
ngOnInit(): void { ngOnInit(): void {
this.aclService.setFull(false);
this.authnService.setRoles(this.aclService);
const { doc, router, destroy$, menuSrv, settings, cdr } = this; const { doc, router, destroy$, menuSrv, settings, cdr } = this;
this.bodyEl = doc.querySelector('body'); this.bodyEl = doc.querySelector('body');
this.openedByUrl(router.url); this.openedByUrl(router.url);
@ -295,6 +300,11 @@ export class LayoutDefaultNavComponent implements OnInit, OnDestroy {
i._hidden = true; i._hidden = true;
} }
} }
if (i.acl && !this.authnService.hasRole(`${i.acl}`)) {
i.disabled = true;
}
if (this.openStrictly) { if (this.openStrictly) {
i._open = i.open != null ? i.open : false; i._open = i.open != null ? i.open : false;
} }

View File

@ -1,24 +1,23 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { DelonACLModule } from '@delon/acl';
import { NzAvatarModule } from 'ng-zorro-antd/avatar'; import { NzAvatarModule } from 'ng-zorro-antd/avatar';
import { NzBadgeModule } from 'ng-zorro-antd/badge'; import { NzBadgeModule } from 'ng-zorro-antd/badge';
import { NzDropDownModule } from 'ng-zorro-antd/dropdown'; import { NzDropDownModule } from 'ng-zorro-antd/dropdown';
@ -44,6 +43,7 @@ const COMPONENTS = [
imports: [ imports: [
CommonModule, CommonModule,
RouterModule, RouterModule,
DelonACLModule.forRoot(),
NzToolTipModule, NzToolTipModule,
NzIconModule, NzIconModule,
NzAvatarModule, NzAvatarModule,
@ -54,4 +54,4 @@ const COMPONENTS = [
declarations: COMPONENTS, declarations: COMPONENTS,
exports: COMPONENTS exports: COMPONENTS
}) })
export class LayoutDefaultModule {} export class LayoutDefaultModule { }

View File

@ -16,6 +16,7 @@
"icon": "anticon-home", "icon": "anticon-home",
"link": "/dashboard/home", "link": "/dashboard/home",
"open":false, "open":false,
"acl": "ROLE_USER",
"children": [] "children": []
}, },
{ {
@ -24,6 +25,7 @@
"link": "/access/sessions", "link": "/access/sessions",
"icon": "anticon-cluster", "icon": "anticon-cluster",
"open":false, "open":false,
"acl": "ROLE_USER",
"children": [] "children": []
}, },
{ {
@ -32,12 +34,14 @@
"link": "/config/setting", "link": "/config/setting",
"icon": "anticon-setting", "icon": "anticon-setting",
"open":false, "open":false,
"acl": "ROLE_USER",
"children": [ "children": [
{ {
"text": "我的资料", "text": "我的资料",
"i18n": "mxk.menu.config.profile", "i18n": "mxk.menu.config.profile",
"link": "/config/profile", "link": "/config/profile",
"icon": "anticon-appstore", "icon": "anticon-appstore",
"acl": "ROLE_USER",
"children": [] "children": []
}, },
{ {
@ -45,6 +49,7 @@
"i18n": "mxk.menu.config.password", "i18n": "mxk.menu.config.password",
"link": "/config/password", "link": "/config/password",
"icon": "anticon-control", "icon": "anticon-control",
"acl": "ROLE_USER",
"children": [] "children": []
}, },
{ {
@ -52,6 +57,7 @@
"i18n": "mxk.menu.config.socialsassociate", "i18n": "mxk.menu.config.socialsassociate",
"link": "/config/socialsassociate", "link": "/config/socialsassociate",
"icon": "anticon-comment", "icon": "anticon-comment",
"acl": "ROLE_USER",
"children": [] "children": []
}, },
{ {
@ -59,6 +65,7 @@
"i18n": "mxk.menu.config.timebased", "i18n": "mxk.menu.config.timebased",
"link": "/config/timebased", "link": "/config/timebased",
"icon": "anticon-send", "icon": "anticon-send",
"acl": "ROLE_USER",
"children": [] "children": []
} }
] ]
@ -69,12 +76,14 @@
"link": "/audit/audit-logins", "link": "/audit/audit-logins",
"icon": "anticon-history", "icon": "anticon-history",
"open":true, "open":true,
"acl": "ROLE_USER",
"children": [ "children": [
{ {
"text": "登录日志", "text": "登录日志",
"i18n": "mxk.menu.audit.logins", "i18n": "mxk.menu.audit.logins",
"link": "/audit/audit-logins", "link": "/audit/audit-logins",
"icon": "anticon-audit", "icon": "anticon-audit",
"acl": "ROLE_USER",
"children": [] "children": []
}, },
{ {
@ -82,6 +91,7 @@
"i18n": "mxk.menu.audit.loginapps", "i18n": "mxk.menu.audit.loginapps",
"link": "/audit/audit-login-apps", "link": "/audit/audit-login-apps",
"icon": "anticon-audit", "icon": "anticon-audit",
"acl": "ROLE_USER",
"children": [] "children": []
} }
] ]
@ -90,8 +100,10 @@
{ {
"text": "后台", "text": "后台",
"i18n": "mxk.menu.mgt", "i18n": "mxk.menu.mgt",
"link": "/mgt", "link": "/authz/mgt",
"externalLink": "/authz/mgt",
"icon": "anticon-cluster", "icon": "anticon-cluster",
"acl": "ROLE_ADMINISTRATORS",
"open":false, "open":false,
"children": [] "children": []
} }

View File

@ -204,7 +204,7 @@
}, },
"accounts":{ "accounts":{
"userId":"用户编号", "userId":"用户编号",
"username":"登录账号", "username":"登录",
"displayName":"用户名", "displayName":"用户名",
"appName":"应用名称", "appName":"应用名称",
"appId":"应用编号", "appId":"应用编号",

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
// This file can be replaced during build by using the `fileReplacements` array. // This file can be replaced during build by using the `fileReplacements` array.
// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.

View File

@ -1,19 +1,18 @@
/* /*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/* /*
* Automatically generated by 'ng g ng-alain:plugin icon' * Automatically generated by 'ng g ng-alain:plugin icon'
@ -107,6 +106,7 @@ import {
DashOutline, DashOutline,
FileProtectOutline, FileProtectOutline,
HistoryOutline, HistoryOutline,
UserAddOutline,
AuditOutline AuditOutline
} from '@ant-design/icons-angular/icons'; } from '@ant-design/icons-angular/icons';
import { QR_DEFULAT_CONFIG } from '@delon/abc/qr'; import { QR_DEFULAT_CONFIG } from '@delon/abc/qr';
@ -198,5 +198,6 @@ export const ICONS_AUTO = [
DashOutline, DashOutline,
FileProtectOutline, FileProtectOutline,
HistoryOutline, HistoryOutline,
UserAddOutline,
AuditOutline AuditOutline
]; ];

View File

@ -1,5 +1,5 @@
/* /*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ package org.maxkey.web.contorller;
import java.util.List; import java.util.List;
import org.maxkey.authn.annotation.CurrentUser; import org.maxkey.authn.annotation.CurrentUser;
import org.maxkey.authn.web.AuthorizationUtils;
import org.maxkey.constants.ConstsStatus; import org.maxkey.constants.ConstsStatus;
import org.maxkey.crypto.password.PasswordReciprocal; import org.maxkey.crypto.password.PasswordReciprocal;
import org.maxkey.entity.Accounts; import org.maxkey.entity.Accounts;
@ -115,7 +114,6 @@ public class AppListController {
@ModelAttribute Accounts account, @ModelAttribute Accounts account,
@CurrentUser UserInfo currentUser) { @CurrentUser UserInfo currentUser) {
Accounts appUsers = new Accounts(); Accounts appUsers = new Accounts();
if (credential == Apps.CREDENTIALS.USER_DEFINED) { if (credential == Apps.CREDENTIALS.USER_DEFINED) {
appUsers = accountsService.load(new Accounts(currentUser.getId(), account.getAppId())); appUsers = accountsService.load(new Accounts(currentUser.getId(), account.getAppId()));
if (appUsers == null) { if (appUsers == null) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top] * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,12 +18,13 @@
package org.maxkey.web.contorller; package org.maxkey.web.contorller;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.maxkey.authn.annotation.CurrentUser; import org.maxkey.authn.annotation.CurrentUser;
import org.maxkey.crypto.Base32Utils; import org.maxkey.crypto.Base32Utils;
import org.maxkey.crypto.Base64Utils;
import org.maxkey.crypto.password.PasswordReciprocal; import org.maxkey.crypto.password.PasswordReciprocal;
import org.maxkey.entity.Message; import org.maxkey.entity.Message;
import org.maxkey.entity.UserInfo; import org.maxkey.entity.UserInfo;
@ -31,7 +32,6 @@ import org.maxkey.password.onetimepwd.algorithm.OtpKeyUriFormat;
import org.maxkey.password.onetimepwd.algorithm.OtpSecret; import org.maxkey.password.onetimepwd.algorithm.OtpSecret;
import org.maxkey.persistence.service.UserInfoService; import org.maxkey.persistence.service.UserInfoService;
import org.maxkey.util.RQCodeUtils; import org.maxkey.util.RQCodeUtils;
import org.maxkey.web.image.ImageEndpoint;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -60,7 +60,8 @@ public class OneTimePasswordController {
@RequestMapping(value = {"/timebased"}) @RequestMapping(value = {"/timebased"})
@ResponseBody @ResponseBody
public ResponseEntity<?> timebased(@RequestParam String generate,@CurrentUser UserInfo currentUser) { public ResponseEntity<?> timebased(
@RequestParam String generate,@CurrentUser UserInfo currentUser) {
HashMap<String,Object >timebased =new HashMap<String,Object >(); HashMap<String,Object >timebased =new HashMap<String,Object >();
generate(generate,currentUser); generate(generate,currentUser);
@ -72,6 +73,8 @@ public class OneTimePasswordController {
String otpauth = otpKeyUriFormat.format(currentUser.getUsername()); String otpauth = otpKeyUriFormat.format(currentUser.getUsername());
byte[] byteSharedSecret = Base32Utils.decode(sharedSecret); byte[] byteSharedSecret = Base32Utils.decode(sharedSecret);
String hexSharedSecret = Hex.encodeHexString(byteSharedSecret); String hexSharedSecret = Hex.encodeHexString(byteSharedSecret);
BufferedImage bufferedImage = RQCodeUtils.write2BufferedImage(otpauth, "gif", 300, 300);
String rqCode = Base64Utils.encodeImage(bufferedImage);
timebased.put("displayName", currentUser.getDisplayName()); timebased.put("displayName", currentUser.getDisplayName());
timebased.put("username", currentUser.getUsername()); timebased.put("username", currentUser.getUsername());
@ -79,7 +82,7 @@ public class OneTimePasswordController {
timebased.put("period", otpKeyUriFormat.getPeriod()); timebased.put("period", otpKeyUriFormat.getPeriod());
timebased.put("sharedSecret", sharedSecret); timebased.put("sharedSecret", sharedSecret);
timebased.put("hexSharedSecret", hexSharedSecret); timebased.put("hexSharedSecret", hexSharedSecret);
timebased.put("rqCode", genRqCode(otpauth)); timebased.put("rqCode", rqCode);
return new Message<HashMap<String,Object >>(timebased).buildResponse(); return new Message<HashMap<String,Object >>(timebased).buildResponse();
} }
@ -96,10 +99,5 @@ public class OneTimePasswordController {
} }
} }
public String genRqCode(String otpauth) {
BufferedImage bufferedImage = RQCodeUtils.write2BufferedImage(otpauth, "gif", 300, 300);
byte[] imageByte = ImageEndpoint.bufferedImage2Byte(bufferedImage);
return "data:image/png;base64," + Base64.getEncoder().encodeToString(imageByte);
}
} }