mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-06 08:59:10 +08:00
user accout
This commit is contained in:
parent
95231504bb
commit
3e080d568f
@ -19,13 +19,9 @@ package org.maxkey.web.contorller;
|
||||
|
||||
import com.google.code.kaptcha.Producer;
|
||||
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.maxkey.authn.jwt.AuthTokenService;
|
||||
import org.maxkey.crypto.Base64Utils;
|
||||
import org.maxkey.entity.Message;
|
||||
import org.maxkey.persistence.MomentaryService;
|
||||
import org.slf4j.Logger;
|
||||
@ -94,16 +90,10 @@ public class ImageCaptchaEndpoint {
|
||||
momentaryService.put("", kaptchaKey, kaptchaValue);
|
||||
// create the image with the text
|
||||
BufferedImage bufferedImage = captchaProducer.createImage(kaptchaText);
|
||||
// write the data out
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
ImageIO.write(bufferedImage, "png", stream);
|
||||
|
||||
String b64Image = "data:image/png;base64," +
|
||||
Base64.getEncoder().encodeToString(stream.toByteArray());
|
||||
String b64Image = Base64Utils.encodeImage(bufferedImage);
|
||||
|
||||
_logger.trace("b64Image {}" , b64Image);
|
||||
|
||||
stream.close();
|
||||
return new Message<ImageCaptcha>(
|
||||
new ImageCaptcha(state,b64Image)
|
||||
).buildResponse();
|
||||
|
||||
@ -17,9 +17,14 @@
|
||||
|
||||
package org.maxkey.crypto;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
/**
|
||||
@ -56,6 +61,25 @@ public final class Base64Utils {
|
||||
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.
|
||||
*
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
package org.maxkey.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@ -29,6 +28,7 @@ import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
|
||||
import org.maxkey.crypto.Base64Utils;
|
||||
import org.maxkey.util.StringUtils;
|
||||
|
||||
/**
|
||||
@ -421,8 +421,7 @@ public class UserInfo extends JpaBaseEntity {
|
||||
|
||||
public void transPictureBase64() {
|
||||
if(picture != null) {
|
||||
this.pictureBase64 = "data:image/png;base64," +
|
||||
Base64.getEncoder().encodeToString(picture);
|
||||
this.pictureBase64 = Base64Utils.encodeImage(picture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -18,7 +18,6 @@
|
||||
package org.maxkey.entity.apps;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
@ -29,6 +28,7 @@ import javax.persistence.Table;
|
||||
|
||||
import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
|
||||
import org.maxkey.constants.ConstsBoolean;
|
||||
import org.maxkey.crypto.Base64Utils;
|
||||
|
||||
@Entity
|
||||
@Table(name = "MXK_APPS")
|
||||
@ -292,8 +292,7 @@ public class Apps extends JpaBaseEntity implements Serializable {
|
||||
|
||||
public void transIconBase64() {
|
||||
if(icon !=null) {
|
||||
this.iconBase64 = "data:image/png;base64," +
|
||||
Base64.getEncoder().encodeToString(icon);
|
||||
this.iconBase64 = Base64Utils.encodeImage(icon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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());
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/* eslint-disable import/order */
|
||||
/* eslint-disable import/no-duplicates */
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { HttpClient } from '@angular/common/http';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
@ -66,7 +65,8 @@ export class StartupService {
|
||||
// 用户信息:包括姓名、头像、邮箱地址
|
||||
//this.settingService.setUser(appData.user);
|
||||
// ACL:设置权限为全量
|
||||
this.aclService.setFull(true);
|
||||
this.aclService.setFull(false);
|
||||
|
||||
// 初始化菜单
|
||||
this.menuService.add(appData.menu);
|
||||
// 设置页面标题的后缀
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/* eslint-disable import/order */
|
||||
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
|
||||
|
||||
@ -1,26 +1,27 @@
|
||||
/*
|
||||
* 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 { Component } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { ACLService } from '@delon/acl';
|
||||
import { SettingsService, User } from '@delon/theme';
|
||||
import { environment } from '@env/environment';
|
||||
import { CONSTS } from 'src/app/shared/consts';
|
||||
|
||||
import { AuthnService } from '../../service/authn.service';
|
||||
import { LayoutDefaultOptions } from '../../theme/layout-default';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { Component, Inject, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@ -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`;
|
||||
}
|
||||
}
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
@ -21,6 +20,7 @@ import { RouterModule, Routes } from '@angular/router';
|
||||
import { SharedModule } from '@shared';
|
||||
|
||||
import { LayoutBlankComponent } from '../../layout/blank/blank.component';
|
||||
import { AuthzMgtComponent } from './authz-mgt.component';
|
||||
import { CredentialComponent } from './credential/credential.component';
|
||||
import { Oauth2ApproveComponent } from './oauth2-approve/oauth2-approve.component';
|
||||
const routes: Routes = [
|
||||
@ -43,6 +43,11 @@ const routes: Routes = [
|
||||
path: 'oauth2approve',
|
||||
component: Oauth2ApproveComponent,
|
||||
data: { title: 'credential', titleI18n: 'app.login.login' }
|
||||
},
|
||||
{
|
||||
path: 'mgt',
|
||||
component: AuthzMgtComponent,
|
||||
data: { title: 'mgt', titleI18n: 'app.login.login' }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, Inject, OnDestroy, Optional } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
@ -70,7 +69,9 @@ export class CredentialComponent implements OnInit {
|
||||
if (res.code == 0) {
|
||||
this.form.model.init(res.data);
|
||||
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 {
|
||||
this.msg.success(`提交失败`);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
@ -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();
|
||||
});
|
||||
});
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -33,6 +33,7 @@ import { ProfileComponent } from './profile/profile.component';
|
||||
import { SocialsAssociateComponent } from './socials-associate/socials-associate.component';
|
||||
import { SocialsProviderComponent } from './socials-provider/socials-provider.component';
|
||||
import { TimebasedComponent } from './timebased/timebased.component';
|
||||
import { AccoutsComponent } from './accouts/accouts.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -62,7 +63,8 @@ const COMPONENTS = [ProfileComponent];
|
||||
TimebasedComponent,
|
||||
SocialsAssociateComponent,
|
||||
PasswordComponent,
|
||||
ProfileComponent
|
||||
ProfileComponent,
|
||||
AccoutsComponent
|
||||
],
|
||||
imports: [SharedModule, CommonModule, RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { NgModule } from '@angular/core';
|
||||
import { CountDownModule } from '@delon/abc/count-down';
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
</ng-template>-->
|
||||
<nz-card-meta [nzTitle]="item.title" [nzAvatar]="nzAvatar" *ngIf="item.protocol == 'Form_Based'">
|
||||
<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>-->
|
||||
</ng-template>
|
||||
</nz-card-meta>
|
||||
|
||||
@ -1,30 +1,36 @@
|
||||
/*
|
||||
* 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 { Platform } from '@angular/cdk/platform';
|
||||
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 { OnboardingService } from '@delon/abc/onboarding';
|
||||
import { ACLService } from '@delon/acl';
|
||||
import { environment } from '@env/environment';
|
||||
import { format } from 'date-fns';
|
||||
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 { AuthnService } from '../../../service/authn.service';
|
||||
import { AccoutsComponent } from '../../config/accouts/accouts.component';
|
||||
|
||||
import { Console } from 'console';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
@ -47,6 +53,8 @@ export class HomeComponent implements OnInit {
|
||||
baseUrl: String = '';
|
||||
|
||||
constructor(
|
||||
private modal: NzModalService,
|
||||
private viewContainerRef: ViewContainerRef,
|
||||
private appListService: AppListService,
|
||||
private cdr: ChangeDetectorRef,
|
||||
private obSrv: OnboardingService,
|
||||
@ -77,15 +85,26 @@ export class HomeComponent implements OnInit {
|
||||
}
|
||||
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 {
|
||||
if (environment.api.baseUrl.endsWith('/')) {
|
||||
this.baseUrl = environment.api.baseUrl.substring(0, environment.api.baseUrl.length - 1);
|
||||
} else {
|
||||
this.baseUrl = environment.api.baseUrl;
|
||||
}
|
||||
|
||||
this.appListService.appList().subscribe(res => {
|
||||
console.log(res.data);
|
||||
//console.log(res.data);
|
||||
this.appList = res.data;
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { Component } from '@angular/core';
|
||||
import { ACLService } from '@delon/acl';
|
||||
@ -36,7 +35,7 @@ export class ACLComponent {
|
||||
return this.aclSrv.data;
|
||||
}
|
||||
|
||||
constructor(private aclSrv: ACLService, private menuSrv: MenuService) {}
|
||||
constructor(private aclSrv: ACLService, private menuSrv: MenuService) { }
|
||||
|
||||
private reMenu(): void {
|
||||
this.menuSrv.resume();
|
||||
|
||||
@ -1,26 +1,25 @@
|
||||
/*
|
||||
* 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 { AuthenticationService } from '../../service/authentication.service';
|
||||
import { AuthnService } from '../../service/authn.service';
|
||||
import { SocialsProviderService } from '../../service/socials-provider.service';
|
||||
|
||||
@Component({
|
||||
@ -34,7 +33,7 @@ export class CallbackComponent implements OnInit {
|
||||
private router: Router,
|
||||
private socialsProviderService: SocialsProviderService,
|
||||
private settingsService: SettingsService,
|
||||
private authenticationService: AuthenticationService,
|
||||
private authnService: AuthnService,
|
||||
@Optional()
|
||||
@Inject(ReuseTabService)
|
||||
private reuseTabService: ReuseTabService,
|
||||
@ -49,9 +48,9 @@ export class CallbackComponent implements OnInit {
|
||||
// 清空路由复用信息
|
||||
this.reuseTabService.clear();
|
||||
// 设置用户Token信息
|
||||
this.authenticationService.auth(res.data);
|
||||
this.authnService.auth(res.data);
|
||||
}
|
||||
this.authenticationService.navigate({});
|
||||
this.authnService.navigate({});
|
||||
});
|
||||
} else {
|
||||
this.socialsProviderService.bind(this.provider, this.route.snapshot.queryParams).subscribe(res => {
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit, OnDestroy, AfterViewInit, Optional } from '@angular/core';
|
||||
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 { finalize } from 'rxjs/operators';
|
||||
|
||||
import { AuthenticationService } from '../../../service/authentication.service';
|
||||
import { AuthnService } from '../../../service/authn.service';
|
||||
import { ImageCaptchaService } from '../../../service/image-captcha.service';
|
||||
import { SocialsProviderService } from '../../../service/socials-provider.service';
|
||||
import { CONSTS } from '../../../shared/consts';
|
||||
@ -65,7 +64,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
fb: FormBuilder,
|
||||
private router: Router,
|
||||
private settingsService: SettingsService,
|
||||
private authenticationService: AuthenticationService,
|
||||
private authnService: AuthnService,
|
||||
private socialsProviderService: SocialsProviderService,
|
||||
private imageCaptchaService: ImageCaptchaService,
|
||||
@Optional()
|
||||
@ -88,7 +87,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
ngOnInit(): void {
|
||||
//set redirect_uri , is BASE64URL
|
||||
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
|
||||
@ -97,8 +96,8 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
//init socials,state
|
||||
this.authenticationService.clear();
|
||||
this.authenticationService
|
||||
this.authnService.clear();
|
||||
this.authnService
|
||||
.get({ remember_me: localStorage.getItem(CONSTS.REMEMBER) })
|
||||
.pipe(
|
||||
finalize(() => {
|
||||
@ -118,8 +117,8 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
// 清空路由复用信息
|
||||
this.reuseTabService.clear();
|
||||
// 设置用户Token信息
|
||||
this.authenticationService.auth(res.data);
|
||||
this.authenticationService.navigate({});
|
||||
this.authnService.auth(res.data);
|
||||
this.authnService.navigate({});
|
||||
} else {
|
||||
this.socials = res.data.socials;
|
||||
this.state = res.data.state;
|
||||
@ -136,7 +135,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
congressLogin(congress: string) {
|
||||
this.authenticationService
|
||||
this.authnService
|
||||
.congress({
|
||||
congress: congress
|
||||
})
|
||||
@ -154,8 +153,8 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
// 清空路由复用信息
|
||||
this.reuseTabService.clear();
|
||||
// 设置用户Token信息
|
||||
this.authenticationService.auth(res.data);
|
||||
this.authenticationService.navigate({});
|
||||
this.authnService.auth(res.data);
|
||||
this.authnService.navigate({});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -199,7 +198,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
this.mobile.updateValueAndValidity({ onlySelf: true });
|
||||
return;
|
||||
}
|
||||
this.authenticationService.produceOtp({ mobile: this.mobile.value }).subscribe(res => {
|
||||
this.authnService.produceOtp({ mobile: this.mobile.value }).subscribe(res => {
|
||||
if (res.code !== 0) {
|
||||
this.msg.success(`发送失败`);
|
||||
}
|
||||
@ -242,7 +241,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.loading = true;
|
||||
this.cdr.detectChanges();
|
||||
this.authenticationService
|
||||
this.authnService
|
||||
.login({
|
||||
authType: this.loginType,
|
||||
state: this.state,
|
||||
@ -271,8 +270,8 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
// 清空路由复用信息
|
||||
this.reuseTabService.clear();
|
||||
// 设置用户Token信息
|
||||
this.authenticationService.auth(res.data);
|
||||
this.authenticationService.navigate({});
|
||||
this.authnService.auth(res.data);
|
||||
this.authnService.navigate({});
|
||||
}
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
@ -287,7 +286,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
getQrCode(): void {
|
||||
this.authenticationService.clearUser();
|
||||
this.authnService.clearUser();
|
||||
this.socialsProviderService.scanqrcode(this.socials.qrScan).subscribe(res => {
|
||||
if (res.code === 0) {
|
||||
if (this.socials.qrScan === 'workweixin') {
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { NgModule, Type } from '@angular/core';
|
||||
import { SharedModule } from '@shared';
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
/*
|
||||
* 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 { Injectable, Inject } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { StartupService } from '@core';
|
||||
import { ACLService } from '@delon/acl';
|
||||
import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
|
||||
import { SettingsService, _HttpClient, User } from '@delon/theme';
|
||||
import * as CryptoJS from 'crypto-js';
|
||||
@ -29,7 +29,7 @@ import { hostname } from 'os';
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthenticationService {
|
||||
export class AuthnService {
|
||||
redirect_uri: string = '';
|
||||
|
||||
constructor(
|
||||
@ -91,6 +91,7 @@ export class AuthenticationService {
|
||||
|
||||
this.cookieService.set(CONSTS.CONGRESS, authJwt.token);
|
||||
this.cookieService.set(CONSTS.ONLINE_TICKET, authJwt.ticket, { domain: subHostName });
|
||||
|
||||
if (authJwt.remeberMe) {
|
||||
localStorage.setItem(CONSTS.REMEMBER, authJwt.remeberMe);
|
||||
}
|
||||
@ -99,6 +100,26 @@ export class AuthenticationService {
|
||||
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) {
|
||||
// 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响
|
||||
this.startupService.load().subscribe(() => {
|
||||
@ -1,24 +1,24 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
export const CONSTS = {
|
||||
CONGRESS: 'congress',
|
||||
ONLINE_TICKET: 'online_ticket',
|
||||
REDIRECT_URI: 'redirect_uri',
|
||||
REMEMBER: 'remember_me',
|
||||
TOKEN: '_token',
|
||||
VERSION: 'v3.5.0 GA'
|
||||
};
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { PageHeaderModule } from '@delon/abc/page-header';
|
||||
import { ResultModule } from '@delon/abc/result';
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { NzAlertModule } from 'ng-zorro-antd/alert';
|
||||
import { NzAvatarModule } from 'ng-zorro-antd/avatar';
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { CommonModule } from '@angular/common';
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
@ -49,6 +48,7 @@ const DIRECTIVES: Array<Type<any>> = [];
|
||||
RouterModule,
|
||||
ReactiveFormsModule,
|
||||
AlainThemeModule.forChild(),
|
||||
DelonACLModule.forRoot(),
|
||||
DelonACLModule,
|
||||
DelonFormModule,
|
||||
...SHARED_DELON_MODULES,
|
||||
|
||||
@ -2,21 +2,23 @@
|
||||
<ul nz-menu nzMode="horizontal" nzTheme="dark" style="text-align: center">
|
||||
<!--一级菜单-->
|
||||
<ng-container *ngFor="let mnav of ls">
|
||||
<li nz-menu-item *ngIf="mnav.children.length == 0" style="min-width: 80px">
|
||||
<a href="#{{ mnav.link }}">{{ mnav.text }}</a>
|
||||
<li nz-menu-item *ngIf="mnav.children.length == 0 && mnav.disabled == false" style="min-width: 80px">
|
||||
<a *ngIf="mnav.externalLink == ''" href="#{{ mnav.link }}">{{ mnav.text }}</a>
|
||||
|
||||
<a *ngIf="mnav.externalLink != ''" href="#{{ mnav.externalLink }}" target="_blank">{{ mnav.text }}</a>
|
||||
</li>
|
||||
<li nz-submenu nzTitle="{{ mnav.text }}" *ngIf="mnav.children.length > 0">
|
||||
<ul>
|
||||
<!--二级菜单-->
|
||||
<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>
|
||||
</li>
|
||||
<li nz-submenu nzTitle="{{ snav.text }}" *ngIf="snav.children.length > 0">
|
||||
<ul>
|
||||
<!--三级菜单-->
|
||||
<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>
|
||||
</li>
|
||||
</ng-container>
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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 { Direction, Directionality } from '@angular/cdk/bidi';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
@ -34,6 +33,7 @@ import {
|
||||
} from '@angular/core';
|
||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { ACLService } from '@delon/acl';
|
||||
import { Menu, MenuIcon, MenuInner, MenuService, SettingsService } from '@delon/theme';
|
||||
import { BooleanInput, InputBoolean, InputNumber, NumberInput, ZoneOutside } from '@delon/util/decorator';
|
||||
import { WINDOW } from '@delon/util/token';
|
||||
@ -41,6 +41,7 @@ import type { NzSafeAny } from 'ng-zorro-antd/core/types';
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { AuthnService } from '../../service/authn.service';
|
||||
import { LayoutDefaultOptions } from './types';
|
||||
|
||||
export interface Nav extends MenuInner {
|
||||
@ -89,6 +90,8 @@ export class LayoutDefaultNavComponent implements OnInit, OnDestroy {
|
||||
|
||||
constructor(
|
||||
private menuSrv: MenuService,
|
||||
private authnService: AuthnService,
|
||||
private aclService: ACLService,
|
||||
private settings: SettingsService,
|
||||
private router: Router,
|
||||
private render: Renderer2,
|
||||
@ -280,6 +283,8 @@ export class LayoutDefaultNavComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.aclService.setFull(false);
|
||||
this.authnService.setRoles(this.aclService);
|
||||
const { doc, router, destroy$, menuSrv, settings, cdr } = this;
|
||||
this.bodyEl = doc.querySelector('body');
|
||||
this.openedByUrl(router.url);
|
||||
@ -295,6 +300,11 @@ export class LayoutDefaultNavComponent implements OnInit, OnDestroy {
|
||||
i._hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (i.acl && !this.authnService.hasRole(`${i.acl}`)) {
|
||||
i.disabled = true;
|
||||
}
|
||||
|
||||
if (this.openStrictly) {
|
||||
i._open = i.open != null ? i.open : false;
|
||||
}
|
||||
|
||||
@ -1,24 +1,23 @@
|
||||
/*
|
||||
* 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 { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { DelonACLModule } from '@delon/acl';
|
||||
import { NzAvatarModule } from 'ng-zorro-antd/avatar';
|
||||
import { NzBadgeModule } from 'ng-zorro-antd/badge';
|
||||
import { NzDropDownModule } from 'ng-zorro-antd/dropdown';
|
||||
@ -44,6 +43,7 @@ const COMPONENTS = [
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
DelonACLModule.forRoot(),
|
||||
NzToolTipModule,
|
||||
NzIconModule,
|
||||
NzAvatarModule,
|
||||
@ -54,4 +54,4 @@ const COMPONENTS = [
|
||||
declarations: COMPONENTS,
|
||||
exports: COMPONENTS
|
||||
})
|
||||
export class LayoutDefaultModule {}
|
||||
export class LayoutDefaultModule { }
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
"icon": "anticon-home",
|
||||
"link": "/dashboard/home",
|
||||
"open":false,
|
||||
"acl": "ROLE_USER",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
@ -24,6 +25,7 @@
|
||||
"link": "/access/sessions",
|
||||
"icon": "anticon-cluster",
|
||||
"open":false,
|
||||
"acl": "ROLE_USER",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
@ -32,12 +34,14 @@
|
||||
"link": "/config/setting",
|
||||
"icon": "anticon-setting",
|
||||
"open":false,
|
||||
"acl": "ROLE_USER",
|
||||
"children": [
|
||||
{
|
||||
"text": "我的资料",
|
||||
"i18n": "mxk.menu.config.profile",
|
||||
"link": "/config/profile",
|
||||
"icon": "anticon-appstore",
|
||||
"acl": "ROLE_USER",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
@ -45,6 +49,7 @@
|
||||
"i18n": "mxk.menu.config.password",
|
||||
"link": "/config/password",
|
||||
"icon": "anticon-control",
|
||||
"acl": "ROLE_USER",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
@ -52,6 +57,7 @@
|
||||
"i18n": "mxk.menu.config.socialsassociate",
|
||||
"link": "/config/socialsassociate",
|
||||
"icon": "anticon-comment",
|
||||
"acl": "ROLE_USER",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
@ -59,6 +65,7 @@
|
||||
"i18n": "mxk.menu.config.timebased",
|
||||
"link": "/config/timebased",
|
||||
"icon": "anticon-send",
|
||||
"acl": "ROLE_USER",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
@ -69,12 +76,14 @@
|
||||
"link": "/audit/audit-logins",
|
||||
"icon": "anticon-history",
|
||||
"open":true,
|
||||
"acl": "ROLE_USER",
|
||||
"children": [
|
||||
{
|
||||
"text": "登录日志",
|
||||
"i18n": "mxk.menu.audit.logins",
|
||||
"link": "/audit/audit-logins",
|
||||
"icon": "anticon-audit",
|
||||
"acl": "ROLE_USER",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
@ -82,6 +91,7 @@
|
||||
"i18n": "mxk.menu.audit.loginapps",
|
||||
"link": "/audit/audit-login-apps",
|
||||
"icon": "anticon-audit",
|
||||
"acl": "ROLE_USER",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
@ -90,8 +100,10 @@
|
||||
{
|
||||
"text": "后台",
|
||||
"i18n": "mxk.menu.mgt",
|
||||
"link": "/mgt",
|
||||
"link": "/authz/mgt",
|
||||
"externalLink": "/authz/mgt",
|
||||
"icon": "anticon-cluster",
|
||||
"acl": "ROLE_ADMINISTRATORS",
|
||||
"open":false,
|
||||
"children": []
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@
|
||||
},
|
||||
"accounts":{
|
||||
"userId":"用户编号",
|
||||
"username":"登录账号",
|
||||
"username":"登录名",
|
||||
"displayName":"用户名",
|
||||
"appName":"应用名称",
|
||||
"appId":"应用编号",
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Automatically generated by 'ng g ng-alain:plugin icon'
|
||||
@ -107,6 +106,7 @@ import {
|
||||
DashOutline,
|
||||
FileProtectOutline,
|
||||
HistoryOutline,
|
||||
UserAddOutline,
|
||||
AuditOutline
|
||||
} from '@ant-design/icons-angular/icons';
|
||||
import { QR_DEFULAT_CONFIG } from '@delon/abc/qr';
|
||||
@ -198,5 +198,6 @@ export const ICONS_AUTO = [
|
||||
DashOutline,
|
||||
FileProtectOutline,
|
||||
HistoryOutline,
|
||||
UserAddOutline,
|
||||
AuditOutline
|
||||
];
|
||||
|
||||
@ -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");
|
||||
* 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 org.maxkey.authn.annotation.CurrentUser;
|
||||
import org.maxkey.authn.web.AuthorizationUtils;
|
||||
import org.maxkey.constants.ConstsStatus;
|
||||
import org.maxkey.crypto.password.PasswordReciprocal;
|
||||
import org.maxkey.entity.Accounts;
|
||||
@ -115,7 +114,6 @@ public class AppListController {
|
||||
@ModelAttribute Accounts account,
|
||||
@CurrentUser UserInfo currentUser) {
|
||||
Accounts appUsers = new Accounts();
|
||||
|
||||
if (credential == Apps.CREDENTIALS.USER_DEFINED) {
|
||||
appUsers = accountsService.load(new Accounts(currentUser.getId(), account.getAppId()));
|
||||
if (appUsers == null) {
|
||||
|
||||
@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -18,12 +18,13 @@
|
||||
package org.maxkey.web.contorller;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.maxkey.authn.annotation.CurrentUser;
|
||||
import org.maxkey.crypto.Base32Utils;
|
||||
import org.maxkey.crypto.Base64Utils;
|
||||
import org.maxkey.crypto.password.PasswordReciprocal;
|
||||
import org.maxkey.entity.Message;
|
||||
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.persistence.service.UserInfoService;
|
||||
import org.maxkey.util.RQCodeUtils;
|
||||
import org.maxkey.web.image.ImageEndpoint;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -60,7 +60,8 @@ public class OneTimePasswordController {
|
||||
|
||||
@RequestMapping(value = {"/timebased"})
|
||||
@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 >();
|
||||
|
||||
generate(generate,currentUser);
|
||||
@ -72,6 +73,8 @@ public class OneTimePasswordController {
|
||||
String otpauth = otpKeyUriFormat.format(currentUser.getUsername());
|
||||
byte[] byteSharedSecret = Base32Utils.decode(sharedSecret);
|
||||
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("username", currentUser.getUsername());
|
||||
@ -79,7 +82,7 @@ public class OneTimePasswordController {
|
||||
timebased.put("period", otpKeyUriFormat.getPeriod());
|
||||
timebased.put("sharedSecret", sharedSecret);
|
||||
timebased.put("hexSharedSecret", hexSharedSecret);
|
||||
timebased.put("rqCode", genRqCode(otpauth));
|
||||
timebased.put("rqCode", rqCode);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user