Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
yujianwangzivayy
MaxKey
提交
fe82cb8c
MaxKey
项目概览
yujianwangzivayy
/
MaxKey
与 Fork 源项目一致
Fork自
MaxKey单点登录官方(MaxKeyTop) / MaxKey
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
MaxKey
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
fe82cb8c
编写于
2月 13, 2023
作者:
M
MaxKey
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'main' of
https://gitee.com/dromara/MaxKey
上级
21854aa7
04cffec7
变更
25
隐藏空白更改
内联
并排
Showing
25 changed file
with
1368 addition
and
50 deletion
+1368
-50
build.gradle
build.gradle
+7
-0
maxkey-authentications/maxkey-authentication-sms/src/main/java/org/maxkey/password/sms/SmsOtpAuthnService.java
...main/java/org/maxkey/password/sms/SmsOtpAuthnService.java
+3
-3
maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/AuthMaxkeyRequest.java
...rc/main/java/me/zhyd/oauth/request/AuthMaxkeyRequest.java
+58
-0
maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/MaxkeyAuthDefaultSource.java
...n/java/me/zhyd/oauth/request/MaxkeyAuthDefaultSource.java
+51
-0
maxkey-authentications/maxkey-authentication-social/src/main/java/org/maxkey/authn/support/socialsignon/SocialSignOnEndpoint.java
...xkey/authn/support/socialsignon/SocialSignOnEndpoint.java
+127
-18
maxkey-authentications/maxkey-authentication-social/src/main/java/org/maxkey/authn/support/socialsignon/service/SocialSignOnProviderService.java
...ort/socialsignon/service/SocialSignOnProviderService.java
+24
-4
maxkey-authentications/maxkey-authentication-social/src/main/java/org/maxkey/authn/support/socialsignon/token/RedisTokenStore.java
...key/authn/support/socialsignon/token/RedisTokenStore.java
+82
-0
maxkey-authentications/maxkey-authentication-social/src/main/java/org/maxkey/autoconfigure/SocialSignOnAutoConfiguration.java
...g/maxkey/autoconfigure/SocialSignOnAutoConfiguration.java
+12
-1
maxkey-web-frontend/maxkey-web-app/src/app/routes/config/socials-provider/socials-provider.component.ts
...tes/config/socials-provider/socials-provider.component.ts
+2
-2
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/callback.component.ts
...key-web-app/src/app/routes/passport/callback.component.ts
+31
-2
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.html
...eb-app/src/app/routes/passport/login/login.component.html
+5
-2
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.less
...eb-app/src/app/routes/passport/login/login.component.less
+2
-1
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.ts
...-web-app/src/app/routes/passport/login/login.component.ts
+52
-1
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/passport.module.ts
...maxkey-web-app/src/app/routes/passport/passport.module.ts
+2
-2
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/socials-provider-bind-user/socials-provider-bind-user.component.html
...vider-bind-user/socials-provider-bind-user.component.html
+30
-0
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/socials-provider-bind-user/socials-provider-bind-user.component.less
...vider-bind-user/socials-provider-bind-user.component.less
+0
-0
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/socials-provider-bind-user/socials-provider-bind-user.component.spec.ts
...er-bind-user/socials-provider-bind-user.component.spec.ts
+42
-0
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/socials-provider-bind-user/socials-provider-bind-user.component.ts
...rovider-bind-user/socials-provider-bind-user.component.ts
+124
-0
maxkey-web-frontend/maxkey-web-app/src/app/service/authn.service.ts
...-frontend/maxkey-web-app/src/app/service/authn.service.ts
+4
-0
maxkey-web-frontend/maxkey-web-app/src/app/service/socials-provider.service.ts
...axkey-web-app/src/app/service/socials-provider.service.ts
+8
-0
maxkey-web-frontend/maxkey-web-app/src/assets/qrcode/qrcode.min.js
...b-frontend/maxkey-web-app/src/assets/qrcode/qrcode.min.js
+614
-0
maxkey-web-frontend/maxkey-web-app/src/environments/environment.ts
...b-frontend/maxkey-web-app/src/environments/environment.ts
+1
-1
maxkey-web-frontend/maxkey-web-app/src/index.html
maxkey-web-frontend/maxkey-web-app/src/index.html
+4
-3
maxkey-webs/maxkey-web-maxkey/build.gradle
maxkey-webs/maxkey-web-maxkey/build.gradle
+36
-6
maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/contorller/LoginEntryPoint.java
.../main/java/org/maxkey/web/contorller/LoginEntryPoint.java
+47
-4
未找到文件。
build.gradle
浏览文件 @
fe82cb8c
...
...
@@ -395,6 +395,13 @@ subprojects {
implementation
group:
'io.netty'
,
name:
'netty-all'
,
version:
"${nettyVersion}"
//阿里云
implementation
group:
'com.aliyun'
,
name:
'aliyun-java-sdk-core'
,
version:
"${aliyunjavasdkcoreVersion}"
// https://mvnrepository.com/artifact/io.opentracing/opentracing-util
implementation
'io.opentracing:opentracing-util:0.33.0'
// https://mvnrepository.com/artifact/io.opentracing/opentracing-api
implementation
'io.opentracing:opentracing-api:0.33.0'
implementation
'io.opentracing:opentracing-noop:0.33.0'
//腾讯云
implementation
group:
'com.tencentcloudapi'
,
name:
'tencentcloud-sdk-java'
,
version:
"${tencentcloudsdkjavaVersion}"
//json
...
...
maxkey-authentications/maxkey-authentication-sms/src/main/java/org/maxkey/password/sms/SmsOtpAuthnService.java
浏览文件 @
fe82cb8c
...
...
@@ -71,7 +71,7 @@ public class SmsOtpAuthnService {
if
(
smsProvider
.
getProvider
().
equalsIgnoreCase
(
"aliyun"
))
{
SmsOtpAuthnAliyun
aliyun
=
new
SmsOtpAuthnAliyun
(
smsProvider
.
getAppKey
(),
smsProvider
.
getAppSecret
(
),
PasswordReciprocal
.
getInstance
().
decoder
(
smsProvider
.
getAppSecret
()
),
smsProvider
.
getTemplateId
(),
smsProvider
.
getSignName
()
);
...
...
@@ -82,7 +82,7 @@ public class SmsOtpAuthnService {
}
else
if
(
smsProvider
.
getProvider
().
equalsIgnoreCase
(
"tencentcloud"
))
{
SmsOtpAuthnTencentCloud
tencentCloud
=
new
SmsOtpAuthnTencentCloud
(
smsProvider
.
getAppKey
(),
smsProvider
.
getAppSecret
(
),
PasswordReciprocal
.
getInstance
().
decoder
(
smsProvider
.
getAppSecret
()
),
smsProvider
.
getSmsSdkAppId
(),
smsProvider
.
getTemplateId
(),
smsProvider
.
getSignName
()
...
...
@@ -94,7 +94,7 @@ public class SmsOtpAuthnService {
}
else
if
(
smsProvider
.
getProvider
().
equalsIgnoreCase
(
"neteasesms"
))
{
SmsOtpAuthnYunxin
yunxin
=
new
SmsOtpAuthnYunxin
(
smsProvider
.
getAppKey
(),
smsProvider
.
getAppSecret
(
),
PasswordReciprocal
.
getInstance
().
decoder
(
smsProvider
.
getAppSecret
()
),
smsProvider
.
getTemplateId
()
);
if
(
redisOptTokenStore
!=
null
)
{
...
...
maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/AuthMaxkeyRequest.java
0 → 100644
浏览文件 @
fe82cb8c
/*
* 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.
*/
package
me.zhyd.oauth.request
;
import
com.alibaba.fastjson.JSONObject
;
import
me.zhyd.oauth.cache.AuthStateCache
;
import
me.zhyd.oauth.config.AuthConfig
;
import
me.zhyd.oauth.enums.AuthUserGender
;
import
me.zhyd.oauth.enums.scope.AuthHuaweiScope
;
import
me.zhyd.oauth.exception.AuthException
;
import
me.zhyd.oauth.model.AuthCallback
;
import
me.zhyd.oauth.model.AuthResponse
;
import
me.zhyd.oauth.model.AuthToken
;
import
me.zhyd.oauth.model.AuthUser
;
import
me.zhyd.oauth.utils.AuthScopeUtils
;
import
me.zhyd.oauth.utils.HttpUtils
;
import
me.zhyd.oauth.utils.UrlBuilder
;
import
java.util.HashMap
;
import
java.util.Map
;
import
static
me
.
zhyd
.
oauth
.
enums
.
AuthResponseStatus
.
SUCCESS
;
public
class
AuthMaxkeyRequest
extends
AuthDefaultRequest
{
public
static
final
String
KEY
=
"maxkey"
;
public
AuthMaxkeyRequest
(
AuthConfig
config
)
{
super
(
config
,
WeLinkAuthDefaultSource
.
HUAWEI_WELINK
);
}
public
AuthMaxkeyRequest
(
AuthConfig
config
,
AuthStateCache
authStateCache
)
{
super
(
config
,
MaxkeyAuthDefaultSource
.
MAXKEY
,
authStateCache
);
}
@Override
protected
AuthToken
getAccessToken
(
AuthCallback
authCallback
)
{
return
null
;
}
@Override
protected
AuthUser
getUserInfo
(
AuthToken
authToken
)
{
return
null
;
}
}
maxkey-authentications/maxkey-authentication-social/src/main/java/me/zhyd/oauth/request/MaxkeyAuthDefaultSource.java
0 → 100644
浏览文件 @
fe82cb8c
/*
* 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.
*/
package
me.zhyd.oauth.request
;
import
me.zhyd.oauth.config.AuthSource
;
public
enum
MaxkeyAuthDefaultSource
implements
AuthSource
{
MAXKEY
{
@Override
public
String
authorize
()
{
return
"https://login.welink.huaweicloud.com/connect/oauth2/sns_authorize"
;
}
@Override
public
String
accessToken
()
{
return
"https://open.welink.huaweicloud.com/api/auth/v2/tickets"
;
}
@Override
public
String
userInfo
()
{
return
"https://open.welink.huaweicloud.com/api/contact/v1/users"
;
}
@Override
public
String
refresh
()
{
return
""
;
}
@Override
public
Class
<?
extends
AuthDefaultRequest
>
getTargetClass
()
{
return
AuthHuaweiWeLinkRequest
.
class
;
}
}
}
maxkey-authentications/maxkey-authentication-social/src/main/java/org/maxkey/authn/support/socialsignon/SocialSignOnEndpoint.java
浏览文件 @
fe82cb8c
...
...
@@ -22,6 +22,8 @@ package org.maxkey.authn.support.socialsignon;
import
javax.servlet.http.HttpServletRequest
;
import
me.zhyd.oauth.request.AuthMaxkeyRequest
;
import
org.apache.commons.lang3.StringUtils
;
import
org.maxkey.authn.LoginCredential
;
import
org.maxkey.authn.annotation.CurrentUser
;
import
org.maxkey.authn.jwt.AuthJwt
;
...
...
@@ -30,18 +32,18 @@ import org.maxkey.entity.Message;
import
org.maxkey.entity.SocialsAssociate
;
import
org.maxkey.entity.SocialsProvider
;
import
org.maxkey.entity.UserInfo
;
import
org.maxkey.uuid.UUID
;
import
org.maxkey.web.WebContext
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
org.springframework.web.bind.annotation.*
;
import
me.zhyd.oauth.request.AuthRequest
;
import
java.util.Map
;
/**
* @author Crystal.Sea
*
...
...
@@ -50,7 +52,7 @@ import me.zhyd.oauth.request.AuthRequest;
@RequestMapping
(
value
=
"/logon/oauth20"
)
public
class
SocialSignOnEndpoint
extends
AbstractSocialSignOnEndpoint
{
final
static
Logger
_logger
=
LoggerFactory
.
getLogger
(
SocialSignOnEndpoint
.
class
);
@RequestMapping
(
value
={
"/authorize/{provider}"
},
method
=
RequestMethod
.
GET
)
@ResponseBody
public
ResponseEntity
<?>
authorize
(
HttpServletRequest
request
,
...
...
@@ -59,13 +61,13 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
_logger
.
trace
(
"SocialSignOn provider : "
+
provider
);
String
instId
=
WebContext
.
getInst
().
getId
();
String
originURL
=
WebContext
.
getHttpContextPath
(
request
,
false
);
String
authorizationUrl
=
String
authorizationUrl
=
buildAuthRequest
(
instId
,
provider
,
originURL
+
applicationConfig
.
getFrontendUri
()
).
authorize
(
authTokenService
.
genRandomJwt
());
_logger
.
trace
(
"authorize SocialSignOn : "
+
authorizationUrl
);
return
new
Message
<
Object
>((
Object
)
authorizationUrl
).
buildResponse
();
}
...
...
@@ -85,7 +87,8 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
if
(
authRequest
==
null
)
{
_logger
.
error
(
"build authRequest fail ."
);
}
String
state
=
authTokenService
.
genRandomJwt
();
String
state
=
UUID
.
generate
().
toString
();
//String state = authTokenService.genRandomJwt();
authRequest
.
authorize
(
state
);
SocialsProvider
socialSignOnProvider
=
socialSignOnProviderService
.
get
(
instId
,
provider
);
...
...
@@ -94,10 +97,14 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
scanQrProvider
.
setRedirectUri
(
socialSignOnProviderService
.
getRedirectUri
(
originURL
+
applicationConfig
.
getFrontendUri
(),
provider
));
//缓存state票据在缓存或者是redis中五分钟过期
if
(
provider
.
equalsIgnoreCase
(
AuthMaxkeyRequest
.
KEY
))
{
socialSignOnProviderService
.
setToken
(
state
);
}
return
new
Message
<
SocialsProvider
>(
scanQrProvider
).
buildResponse
();
}
}
@RequestMapping
(
value
={
"/bind/{provider}"
},
method
=
RequestMethod
.
GET
)
public
ResponseEntity
<?>
bind
(
@PathVariable
String
provider
,
...
...
@@ -105,7 +112,7 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
HttpServletRequest
request
)
{
//auth call back may exception
try
{
String
originURL
=
WebContext
.
getHttpContextPath
(
request
,
false
);
String
originURL
=
WebContext
.
getHttpContextPath
(
request
,
false
);
SocialsAssociate
socialsAssociate
=
this
.
authCallback
(
userInfo
.
getInstId
(),
provider
,
originURL
+
applicationConfig
.
getFrontendUri
());
socialsAssociate
.
setSocialUserInfo
(
accountJsonString
);
...
...
@@ -125,6 +132,8 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
return
new
Message
<
AuthJwt
>(
Message
.
ERROR
).
buildResponse
();
}
@RequestMapping
(
value
={
"/callback/{provider}"
},
method
=
RequestMethod
.
GET
)
public
ResponseEntity
<?>
callback
(
@PathVariable
String
provider
,
HttpServletRequest
request
)
{
...
...
@@ -134,15 +143,20 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
String
instId
=
WebContext
.
getInst
().
getId
();
SocialsAssociate
socialsAssociate
=
this
.
authCallback
(
instId
,
provider
,
originURL
+
applicationConfig
.
getFrontendUri
());
SocialsAssociate
socialssssociate1
=
this
.
socialsAssociateService
.
get
(
socialsAssociate
);
socialsAssociate
=
this
.
socialsAssociateService
.
get
(
socialsAssociate
);
_logger
.
debug
(
"Loaded SocialSignOn Socials Associate : "
+
socialsAssociate
);
if
(
null
==
socialsAssociate
)
{
return
new
Message
<
AuthJwt
>(
Message
.
ERROR
).
buildResponse
();
}
_logger
.
debug
(
"Loaded SocialSignOn Socials Associate : "
+
socialssssociate1
);
if
(
null
==
socialssssociate1
)
{
//如果存在第三方ID并且在数据库无法找到映射关系,则进行绑定逻辑
if
(
StringUtils
.
isNotEmpty
(
socialsAssociate
.
getSocialUserId
()))
{
//返回message为第三方用户标识
return
new
Message
<
AuthJwt
>(
Message
.
PROMPT
,
socialsAssociate
.
getSocialUserId
()).
buildResponse
();
}
}
socialsAssociate
=
socialssssociate1
;
_logger
.
debug
(
"Social Sign On from {} mapping to user {}"
,
socialsAssociate
.
getProvider
(),
socialsAssociate
.
getUsername
());
...
...
@@ -163,4 +177,99 @@ public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
return
new
Message
<
AuthJwt
>(
Message
.
ERROR
).
buildResponse
();
}
}
/**
* 提供给第三方应用关联用户接口
* @return
*/
@RequestMapping
(
value
={
"/workweixin/qr/auth/login"
},
method
=
{
RequestMethod
.
POST
})
public
ResponseEntity
<?>
qrAuthLogin
(
@RequestParam
Map
<
String
,
String
>
param
,
HttpServletRequest
request
)
{
try
{
if
(
null
==
param
){
return
new
Message
<
AuthJwt
>(
Message
.
ERROR
).
buildResponse
();
}
String
token
=
param
.
get
(
"token"
);
String
username
=
param
.
get
(
"username"
);
//判断token是否合法
String
redisusername
=
this
.
socialSignOnProviderService
.
getToken
(
token
);
if
(
StringUtils
.
isNotEmpty
(
redisusername
)){
//设置token和用户绑定
boolean
flag
=
this
.
socialSignOnProviderService
.
bindtoken
(
token
,
username
);
if
(
flag
)
{
return
new
Message
<
AuthJwt
>().
buildResponse
();
}
}
else
{
return
new
Message
<
AuthJwt
>(
Message
.
WARNING
,
"Invalid token"
).
buildResponse
();
}
}
catch
(
Exception
e
)
{
_logger
.
error
(
"qrAuthLogin Exception "
,
e
);
}
return
new
Message
<
AuthJwt
>(
Message
.
ERROR
).
buildResponse
();
}
/**
* maxkey 监听扫码回调
* @param provider
* @param state
* @param request
* @return
*/
@RequestMapping
(
value
={
"/qrcallback/{provider}/{state}"
},
method
=
RequestMethod
.
GET
)
public
ResponseEntity
<?>
qrcallback
(
@PathVariable
String
provider
,
@PathVariable
String
state
,
HttpServletRequest
request
)
{
try
{
//判断只有maxkey扫码
if
(!
provider
.
equalsIgnoreCase
(
AuthMaxkeyRequest
.
KEY
))
{
return
new
Message
<
AuthJwt
>(
Message
.
ERROR
).
buildResponse
();
}
String
loginName
=
socialSignOnProviderService
.
getToken
(
state
);
if
(
StringUtils
.
isEmpty
(
loginName
))
{
//二维码过期
return
new
Message
<
AuthJwt
>(
Message
.
PROMPT
).
buildResponse
();
}
if
(
"-1"
.
equalsIgnoreCase
(
loginName
)){
//暂无用户扫码
return
new
Message
<
AuthJwt
>(
Message
.
WARNING
).
buildResponse
();
}
String
instId
=
WebContext
.
getInst
().
getId
();
SocialsAssociate
socialsAssociate
=
new
SocialsAssociate
();
socialsAssociate
.
setProvider
(
provider
);
socialsAssociate
.
setSocialUserId
(
loginName
);
socialsAssociate
.
setInstId
(
instId
);
socialsAssociate
=
this
.
socialsAssociateService
.
get
(
socialsAssociate
);
_logger
.
debug
(
"qrcallback Loaded SocialSignOn Socials Associate : "
+
socialsAssociate
);
if
(
null
==
socialsAssociate
)
{
return
new
Message
<
AuthJwt
>(
Message
.
ERROR
).
buildResponse
();
}
_logger
.
debug
(
"qrcallback Social Sign On from {} mapping to user {}"
,
socialsAssociate
.
getProvider
(),
socialsAssociate
.
getUsername
());
LoginCredential
loginCredential
=
new
LoginCredential
(
socialsAssociate
.
getUsername
(),
""
,
ConstsLoginType
.
SOCIALSIGNON
);
SocialsProvider
socialSignOnProvider
=
socialSignOnProviderService
.
get
(
instId
,
provider
);
loginCredential
.
setProvider
(
socialSignOnProvider
.
getProviderName
());
Authentication
authentication
=
authenticationProvider
.
authenticate
(
loginCredential
,
true
);
//socialsAssociate.setAccessToken(JsonUtils.object2Json(this.accessToken));
socialsAssociate
.
setSocialUserInfo
(
accountJsonString
);
//socialsAssociate.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject()));
this
.
socialsAssociateService
.
update
(
socialsAssociate
);
return
new
Message
<
AuthJwt
>(
authTokenService
.
genAuthJwt
(
authentication
)).
buildResponse
();
}
catch
(
Exception
e
)
{
_logger
.
error
(
"qrcallback Exception "
,
e
);
return
new
Message
<
AuthJwt
>(
Message
.
ERROR
).
buildResponse
();
}
}
}
maxkey-authentications/maxkey-authentication-social/src/main/java/org/maxkey/authn/support/socialsignon/service/SocialSignOnProviderService.java
浏览文件 @
fe82cb8c
...
...
@@ -24,6 +24,7 @@ import java.util.HashMap;
import
java.util.List
;
import
java.util.concurrent.TimeUnit
;
import
org.maxkey.authn.support.socialsignon.token.RedisTokenStore
;
import
org.maxkey.constants.ConstsTimeInterval
;
import
org.maxkey.crypto.password.PasswordReciprocal
;
import
org.maxkey.entity.SocialsProvider
;
...
...
@@ -54,6 +55,9 @@ public class SocialSignOnProviderService{
HashMap
<
String
,
SocialsProvider
>
socialSignOnProviderMaps
=
new
HashMap
<
String
,
SocialsProvider
>();
private
final
JdbcTemplate
jdbcTemplate
;
RedisTokenStore
redisTokenStore
;
public
SocialSignOnProviderService
(
JdbcTemplate
jdbcTemplate
)
{
this
.
jdbcTemplate
=
jdbcTemplate
;
...
...
@@ -62,6 +66,17 @@ public class SocialSignOnProviderService{
public
SocialsProvider
get
(
String
instId
,
String
provider
){
return
socialSignOnProviderMaps
.
get
(
instId
+
"_"
+
provider
);
}
public
void
setToken
(
String
token
){
this
.
redisTokenStore
.
store
(
token
);
}
public
boolean
bindtoken
(
String
token
,
String
loginName
){
return
this
.
redisTokenStore
.
bindtoken
(
token
,
loginName
);
}
public
String
getToken
(
String
token
){
return
this
.
redisTokenStore
.
get
(
token
);
}
public
String
getRedirectUri
(
String
baseUri
,
String
provider
)
{
return
baseUri
+
"/passport/callback/"
+
provider
;
...
...
@@ -129,10 +144,10 @@ public class SocialSignOnProviderService{
authRequest
=
new
AuthWeChatEnterpriseWebRequest
(
authConfig
);
}
else
if
(
provider
.
equalsIgnoreCase
(
"welink"
))
{
authRequest
=
new
AuthHuaweiWeLinkRequest
(
authConfig
);
}
}
else
if
(
provider
.
equalsIgnoreCase
(
"maxkey"
))
{
authRequest
=
new
AuthMaxkeyRequest
(
authConfig
);
}
return
authRequest
;
}
...
...
@@ -234,4 +249,9 @@ public class SocialSignOnProviderService{
return
socialsProvider
;
}
}
public
void
setRedisTokenStore
(
RedisTokenStore
redisTokenStore
)
{
this
.
redisTokenStore
=
redisTokenStore
;
}
}
maxkey-authentications/maxkey-authentication-social/src/main/java/org/maxkey/authn/support/socialsignon/token/RedisTokenStore.java
0 → 100644
浏览文件 @
fe82cb8c
/*
* 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.authn.support.socialsignon.token
;
import
org.apache.commons.lang3.StringUtils
;
import
org.joda.time.DateTime
;
import
org.maxkey.constants.ConstsTimeInterval
;
import
org.maxkey.persistence.redis.RedisConnection
;
import
org.maxkey.persistence.redis.RedisConnectionFactory
;
import
java.util.concurrent.ConcurrentHashMap
;
public
class
RedisTokenStore
{
protected
int
validitySeconds
=
ConstsTimeInterval
.
ONE_MINUTE
*
2
;
private
final
ConcurrentHashMap
<
String
,
String
>
tokenStore
=
new
ConcurrentHashMap
<
String
,
String
>();
public
RedisTokenStore
()
{
super
();
}
public
static
String
PREFIX
=
"REDIS_QRSCRAN_SERVICE_"
;
public
void
store
(
String
token
)
{
tokenStore
.
put
(
PREFIX
+
token
,
"-1"
);
/* DateTime currentDateTime = new DateTime();
RedisConnection conn = connectionFactory.getConnection();
conn.getConn().setex(PREFIX + token, validitySeconds, "-1");
conn.close();*/
}
public
boolean
bindtoken
(
String
token
,
String
loginname
)
{
boolean
flag
=
false
;
try
{
/* DateTime currentDateTime = new DateTime();
RedisConnection conn = connectionFactory.getConnection();
conn.getConn().setex(PREFIX + token, validitySeconds, loginname);
//conn.setexObject(PREFIX + token, validitySeconds, loginname);
conn.close();*/
tokenStore
.
put
(
PREFIX
+
token
,
loginname
);
return
true
;
}
catch
(
Exception
e
)
{
}
return
flag
;
}
public
String
get
(
String
token
)
{
/* RedisConnection conn = connectionFactory.getConnection();
String value = conn.get(PREFIX + token);
if(StringUtils.isNotEmpty(value) && !"-1".equalsIgnoreCase(value)) {
conn.delete(PREFIX + token);
return value;
}*/
String
value
=
tokenStore
.
get
(
PREFIX
+
token
);
if
(
StringUtils
.
isNotEmpty
(
value
)
&&
!
"-1"
.
equalsIgnoreCase
(
value
))
{
tokenStore
.
remove
(
PREFIX
+
token
);
return
value
;
}
return
value
;
}
}
maxkey-authentications/maxkey-authentication-social/src/main/java/org/maxkey/autoconfigure/SocialSignOnAutoConfiguration.java
浏览文件 @
fe82cb8c
...
...
@@ -20,10 +20,14 @@ package org.maxkey.autoconfigure;
import
java.io.IOException
;
import
org.maxkey.authn.support.socialsignon.service.JdbcSocialsAssociateService
;
import
org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService
;
import
org.maxkey.authn.support.socialsignon.token.RedisTokenStore
;
import
org.maxkey.constants.ConstsPersistence
;
import
org.maxkey.entity.SocialsProvider
;
import
org.maxkey.persistence.redis.RedisConnectionFactory
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.AutoConfiguration
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.context.annotation.Bean
;
...
...
@@ -40,10 +44,17 @@ public class SocialSignOnAutoConfiguration implements InitializingBean {
@Bean
(
name
=
"socialSignOnProviderService"
)
@ConditionalOnClass
(
SocialsProvider
.
class
)
public
SocialSignOnProviderService
socialSignOnProviderService
(
JdbcTemplate
jdbcTemplate
)
throws
IOException
{
@Value
(
"${maxkey.server.persistence}"
)
int
persistence
,
JdbcTemplate
jdbcTemplate
,
RedisConnectionFactory
redisConnFactory
)
throws
IOException
{
SocialSignOnProviderService
socialSignOnProviderService
=
new
SocialSignOnProviderService
(
jdbcTemplate
);
//load default Social Providers from database
socialSignOnProviderService
.
loadSocials
(
"1"
);
RedisTokenStore
redisTokenStore
=
new
RedisTokenStore
();
socialSignOnProviderService
.
setRedisTokenStore
(
redisTokenStore
);
_logger
.
debug
(
"SocialSignOnProviderService inited."
);
return
socialSignOnProviderService
;
}
...
...
maxkey-web-frontend/maxkey-web-app/src/app/routes/config/socials-provider/socials-provider.component.ts
浏览文件 @
fe82cb8c
...
...
@@ -123,7 +123,7 @@ export class SocialsProviderComponent implements OnInit {
onAdd
(
e
:
MouseEvent
):
void
{
e
.
preventDefault
();
const
modal
=
this
.
modalService
.
create
({
//nzContent: SocialsProvider
Edit
erComponent,
//nzContent: SocialsProvider
BindUs
erComponent,
nzViewContainerRef
:
this
.
viewContainerRef
,
nzComponentParams
:
{
isEdit
:
false
,
...
...
@@ -143,7 +143,7 @@ export class SocialsProviderComponent implements OnInit {
e
.
preventDefault
();
const
modal
=
this
.
modalService
.
create
({
//nzContent: SocialsProvider
Edit
erComponent,
//nzContent: SocialsProvider
BindUs
erComponent,
nzViewContainerRef
:
this
.
viewContainerRef
,
nzComponentParams
:
{
isEdit
:
true
,
...
...
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/callback.component.ts
浏览文件 @
fe82cb8c
...
...
@@ -14,13 +14,14 @@
* limitations under the License.
*/
import
{
Inject
,
Optional
,
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
Inject
,
Optional
,
Component
,
OnInit
,
ViewContainerRef
}
from
'
@angular/core
'
;
import
{
ActivatedRoute
,
Router
}
from
'
@angular/router
'
;
import
{
ReuseTabService
}
from
'
@delon/abc/reuse-tab
'
;
import
{
SettingsService
}
from
'
@delon/theme
'
;
import
{
NzModalRef
,
NzModalService
}
from
'
ng-zorro-antd/modal
'
;
import
{
AuthnService
}
from
'
../../service/authn.service
'
;
import
{
SocialsProviderService
}
from
'
../../service/socials-provider.service
'
;
import
{
SocialsProviderBindUserComponent
}
from
"
./socials-provider-bind-user/socials-provider-bind-user.component
"
;
@
Component
({
selector
:
'
app-callback
'
,
...
...
@@ -30,6 +31,8 @@ export class CallbackComponent implements OnInit {
provider
=
''
;
constructor
(
private
viewContainerRef
:
ViewContainerRef
,
private
modalService
:
NzModalService
,
private
router
:
Router
,
private
socialsProviderService
:
SocialsProviderService
,
private
settingsService
:
SettingsService
,
...
...
@@ -50,6 +53,11 @@ export class CallbackComponent implements OnInit {
// 设置用户Token信息
this
.
authnService
.
auth
(
res
.
data
);
}
else
if
(
res
.
code
===
102
)
{
//绑定用户
this
.
openBindUser
(
res
.
message
)
return
;
}
this
.
authnService
.
navigate
({});
});
}
else
{
...
...
@@ -60,4 +68,25 @@ export class CallbackComponent implements OnInit {
});
}
}
openBindUser
(
socialUserId
:
String
)
{
console
.
log
(
"
bind user :
"
,
this
.
provider
,
socialUserId
);
const
modal
=
this
.
modalService
.
create
({
nzContent
:
SocialsProviderBindUserComponent
,
nzViewContainerRef
:
this
.
viewContainerRef
,
nzComponentParams
:
{
socialUserId
:
socialUserId
,
provider
:
this
.
provider
},
nzOnOk
:
()
=>
new
Promise
(
resolve
=>
setTimeout
(
resolve
,
1000
))
});
// Return a result when closed
modal
.
afterClose
.
subscribe
(
result
=>
{
if
(
result
.
refresh
)
{
}
});
}
}
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.html
浏览文件 @
fe82cb8c
...
...
@@ -82,8 +82,11 @@
</nz-form-control>
</nz-form-item>
</div>
<div
nz-row
style=
"{{ loginType == 'qrscan' ? '' : 'display: none;' }}"
>
<div
class=
"qrcode"
id=
"div_qrcodelogin"
>
</div>
<div
nz-row
*ngIf=
"loginType=='qrscan'"
>
<div
class=
"qrcode"
id=
"div_qrcodelogin"
style=
"background: #fff;padding: 20px;"
>
</div>
<div
id=
"qrexpire"
*ngIf=
"qrexpire"
style=
"width: 100%;text-align: center;background: #fff;padding-bottom: 20px;"
>
二维码过期
<a
href=
"javascript:"
(click)=
"getQrCode()"
>
刷新
</a>
</div>
</div>
<nz-form-item
*ngIf=
"loginType == 'normal' || loginType == 'mobile'"
>
<nz-col
[nzSpan]=
"12"
>
...
...
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.less
浏览文件 @
fe82cb8c
@import '@delon/theme/index';
:host {
display: block;
width: 368px;
...
...
@@ -81,4 +82,4 @@ input{
.qrcode iframe{
border: 0;
}
\ No newline at end of file
}
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/login/login.component.ts
浏览文件 @
fe82cb8c
...
...
@@ -31,6 +31,7 @@ import { ImageCaptchaService } from '../../../service/image-captcha.service';
import
{
SocialsProviderService
}
from
'
../../../service/socials-provider.service
'
;
import
{
CONSTS
}
from
'
../../../shared/consts
'
;
import
{
stringify
}
from
'
querystring
'
;
@
Component
({
...
...
@@ -54,6 +55,7 @@ export class UserLoginComponent implements OnInit, OnDestroy {
loginType
=
'
normal
'
;
loading
=
false
;
passwordVisible
=
false
;
qrexpire
=
false
;
imageCaptcha
=
''
;
captchaType
=
''
;
state
=
''
;
...
...
@@ -287,6 +289,10 @@ export class UserLoginComponent implements OnInit, OnDestroy {
}
getQrCode
():
void
{
this
.
qrexpire
=
false
;
if
(
this
.
interval$
)
{
clearInterval
(
this
.
interval$
);
}
this
.
authnService
.
clearUser
();
this
.
socialsProviderService
.
scanqrcode
(
this
.
socials
.
qrScan
).
subscribe
(
res
=>
{
if
(
res
.
code
===
0
)
{
...
...
@@ -294,11 +300,14 @@ export class UserLoginComponent implements OnInit, OnDestroy {
this
.
qrScanWorkweixin
(
res
.
data
);
}
else
if
(
this
.
socials
.
qrScan
===
'
dingtalk
'
)
{
this
.
qrScanDingtalk
(
res
.
data
);
}
else
if
(
this
.
socials
.
qrScan
===
'
feishu
'
)
{
}
else
if
(
this
.
socials
.
qrScan
===
'
maxkey
'
)
{
this
.
qrScanMaxkey
(
res
.
data
);
}
else
if
(
this
.
socials
.
qrScan
===
'
feishu
'
)
{
this
.
qrScanFeishu
(
res
.
data
);
}
}
});
}
// #endregion
...
...
@@ -364,4 +373,46 @@ export class UserLoginComponent implements OnInit, OnDestroy {
});
}
// #region QR Scan end
qrScanMaxkey
(
data
:
any
)
{
// @ts-ignore
document
.
getElementById
(
"
div_qrcodelogin
"
).
innerHTML
=
''
;
// @ts-ignore
var
qrcode
=
new
QRCode
(
"
div_qrcodelogin
"
,
{
width
:
200
,
height
:
200
,
colorDark
:
"
#000000
"
,
colorLight
:
"
#ffffff
"
}).
makeCode
(
data
.
state
);
//3分钟监听二维码
this
.
count
=
90
;
this
.
interval$
=
setInterval
(()
=>
{
this
.
count
-=
1
;
if
(
this
.
loginType
!=
'
qrscan
'
)
{
clearInterval
(
this
.
interval$
);
}
if
(
this
.
count
<=
0
)
{
clearInterval
(
this
.
interval$
);
}
//轮询发送监听请求
this
.
socialsProviderService
.
qrcallback
(
this
.
socials
.
qrScan
,
data
.
state
).
subscribe
(
res
=>
{
if
(
res
.
code
===
0
)
{
// 清空路由复用信息
this
.
reuseTabService
.
clear
();
// 设置用户Token信息
this
.
authnService
.
auth
(
res
.
data
);
this
.
authnService
.
navigate
({});
clearInterval
(
this
.
interval$
);
}
else
if
(
res
.
code
===
102
)
{
// 二维码过期
clearInterval
(
this
.
interval$
);
this
.
qrexpire
=
true
;
this
.
cdr
.
detectChanges
();
}
else
if
(
res
.
code
===
103
)
{
// 暂无用户扫码
}
});
this
.
cdr
.
detectChanges
();
},
2000
);
}
}
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/passport.module.ts
浏览文件 @
fe82cb8c
...
...
@@ -17,8 +17,8 @@
import
{
NgModule
}
from
'
@angular/core
'
;
import
{
SharedModule
}
from
'
@shared
'
;
import
{
NzStepsModule
}
from
'
ng-zorro-antd/steps
'
;
import
{
CallbackComponent
}
from
'
./callback.component
'
;
import
{
SocialsProviderBindUserComponent
}
from
'
./socials-provider-bind-user/socials-provider-bind-user.component
'
;
import
{
ForgotComponent
}
from
'
./forgot/forgot.component
'
;
import
{
UserLockComponent
}
from
'
./lock/lock.component
'
;
import
{
UserLoginComponent
}
from
'
./login/login.component
'
;
...
...
@@ -26,7 +26,7 @@ import { PassportRoutingModule } from './passport-routing.module';
import
{
UserRegisterResultComponent
}
from
'
./register-result/register-result.component
'
;
import
{
UserRegisterComponent
}
from
'
./register/register.component
'
;
const
COMPONENTS
=
[
UserLoginComponent
,
UserRegisterResultComponent
,
UserRegisterComponent
,
UserLockComponent
,
CallbackComponent
];
const
COMPONENTS
=
[
SocialsProviderBindUserComponent
,
UserLoginComponent
,
UserRegisterResultComponent
,
UserRegisterComponent
,
UserLockComponent
,
CallbackComponent
];
@
NgModule
({
imports
:
[
SharedModule
,
PassportRoutingModule
,
NzStepsModule
],
...
...
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/socials-provider-bind-user/socials-provider-bind-user.component.html
0 → 100644
浏览文件 @
fe82cb8c
<div
*nzModalTitle
>
绑定
</div>
<div>
<form
nz-form
[formGroup]=
"formGroup"
(ngSubmit)=
"onSubmit($event)"
se-container=
"1"
>
<nz-form-item
style=
"width: 100%"
>
<nz-form-control
nzErrorTip=
"Please input your telephone!"
>
<nz-input-group
nzSize=
"large"
nzPrefixIcon=
"user"
>
<input
nz-input
formControlName=
"telephone"
placeholder=
"{{ 'mxk.login.text.mobile' | i18n }}"
/>
</nz-input-group>
</nz-form-control>
</nz-form-item>
<nz-form-item
style=
"width: 100%"
>
<nz-form-control
nzErrorTip=
"Please input your verification code!"
>
<nz-input-group
nzSize=
"large"
nzPrefixIcon=
"mail"
nzSearch
[nzAddOnAfter]=
"suffixSendOtpCodeButton"
>
<input
nz-input
formControlName=
"verificationCode"
placeholder=
"{{ 'mxk.login.text.captcha' | i18n }}"
/>
</nz-input-group>
<ng-template
#suffixSendOtpCodeButton
>
<button
type=
"button"
nz-button
nzSize=
"large"
(click)=
"sendOtpCode()"
[disabled]=
"count > 0"
nzBlock
[nzLoading]=
"loading"
>
{{ count ? count + 's' : ('app.register.get-verification-code' | i18n) }}
</button>
</ng-template>
</nz-form-control>
</nz-form-item>
</form>
</div>
<div
*nzModalFooter
>
<button
nz-button
nzType=
"default"
(click)=
"onClose($event)"
>
{{ 'mxk.text.close' | i18n }}
</button>
<button
nz-button
nzType=
"primary"
(click)=
"onSubmit($event)"
>
{{ 'mxk.text.submit' | i18n }}
</button>
</div>
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/socials-provider-bind-user/socials-provider-bind-user.component.less
0 → 100644
浏览文件 @
fe82cb8c
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/socials-provider-bind-user/socials-provider-bind-user.component.spec.ts
0 → 100644
浏览文件 @
fe82cb8c
/*
* 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
{
ComponentFixture
,
TestBed
}
from
'
@angular/core/testing
'
;
import
{
SocialsProviderBindUserComponent
}
from
'
./socials-provider-bind-user.component
'
;
describe
(
'
SocialsProviderBindUserComponent
'
,
()
=>
{
let
component
:
SocialsProviderBindUserComponent
;
let
fixture
:
ComponentFixture
<
SocialsProviderBindUserComponent
>
;
beforeEach
(
async
()
=>
{
await
TestBed
.
configureTestingModule
({
declarations
:
[
SocialsProviderBindUserComponent
]
})
.
compileComponents
();
});
beforeEach
(()
=>
{
fixture
=
TestBed
.
createComponent
(
SocialsProviderBindUserComponent
);
component
=
fixture
.
componentInstance
;
fixture
.
detectChanges
();
});
it
(
'
should create
'
,
()
=>
{
expect
(
component
).
toBeTruthy
();
});
});
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/socials-provider-bind-user/socials-provider-bind-user.component.ts
0 → 100644
浏览文件 @
fe82cb8c
/*
* 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
,
ChangeDetectorRef
,
Input
,
OnInit
,
Inject
}
from
'
@angular/core
'
;
import
{
FormBuilder
,
FormGroup
,
Validators
}
from
'
@angular/forms
'
;
import
{
I18NService
}
from
'
@core
'
;
import
{
_HttpClient
,
ALAIN_I18N_TOKEN
,
SettingsService
}
from
'
@delon/theme
'
;
import
format
from
'
date-fns/format
'
;
import
{
NzMessageService
}
from
'
ng-zorro-antd/message
'
;
import
{
NzModalRef
,
NzModalService
}
from
'
ng-zorro-antd/modal
'
;
import
{
AuthnService
}
from
"
../../../service/authn.service
"
;
import
{
SocialsProviderService
}
from
"
../../../service/socials-provider.service
"
;
import
{
ReuseTabService
}
from
"
@delon/abc/reuse-tab
"
;
@
Component
({
selector
:
'
app-socials-provider-binduser
'
,
templateUrl
:
'
./socials-provider-bind-user.component.html
'
,
styles
:
[
`
nz-form-item {
width: 100%;
}
`
],
styleUrls
:
[
'
./socials-provider-bind-user.component.less
'
]
})
export
class
SocialsProviderBindUserComponent
implements
OnInit
{
@
Input
()
socialUserId
?:
String
;
@
Input
()
provider
?:
String
;
loading
=
false
;
count
=
0
;
formGroup
:
FormGroup
=
new
FormGroup
({});
interval$
:
any
;
constructor
(
private
modalRef
:
NzModalRef
,
private
fb
:
FormBuilder
,
private
authnService
:
AuthnService
,
private
msg
:
NzMessageService
,
private
socialsProviderService
:
SocialsProviderService
,
@
Inject
(
ALAIN_I18N_TOKEN
)
private
i18n
:
I18NService
,
@
Inject
(
ReuseTabService
)
private
reuseTabService
:
ReuseTabService
,
private
cdr
:
ChangeDetectorRef
)
{}
ngOnInit
():
void
{
this
.
formGroup
=
this
.
fb
.
group
({
telephone
:
[
null
,
[
Validators
.
required
]],
verificationCode
:
[
null
,
[
Validators
.
required
]]
});
console
.
log
(
"
bind open form :
"
,
this
.
provider
,
this
.
socialUserId
)
}
onClose
(
e
:
MouseEvent
):
void
{
e
.
preventDefault
();
this
.
modalRef
.
destroy
({
refresh
:
false
});
}
onSubmit
(
e
:
MouseEvent
):
void
{
console
.
log
(
"
this.formGroup.valid
"
,
this
.
formGroup
.
valid
)
//表单验证
if
(
this
.
formGroup
.
valid
)
{
let
request
=
{
username
:
this
.
socialUserId
,
mobile
:
this
.
formGroup
.
get
(
'
telephone
'
)?.
value
,
code
:
this
.
formGroup
.
get
(
'
verificationCode
'
)?.
value
,
authType
:
this
.
provider
}
this
.
authnService
.
bindSocialsUser
(
request
).
subscribe
(
res
=>
{
if
(
res
.
code
===
0
)
{
// 清空路由复用信息
this
.
reuseTabService
.
clear
();
// 设置用户Token信息
this
.
authnService
.
auth
(
res
.
data
);
this
.
authnService
.
navigate
({});
}
else
{
this
.
msg
.
error
(
`绑定失败`
);
}
});
}
else
{
Object
.
values
(
this
.
formGroup
.
controls
).
forEach
(
control
=>
{
if
(
control
.
invalid
)
{
control
.
markAsDirty
();
control
.
updateValueAndValidity
({
onlySelf
:
true
});
}
});
}
e
.
preventDefault
();
}
sendOtpCode
():
void
{
this
.
authnService
.
produceOtp
({
mobile
:
this
.
formGroup
.
get
(
'
telephone
'
)?.
value
}).
subscribe
(
res
=>
{
if
(
res
.
code
!==
0
)
{
this
.
msg
.
error
(
`发送失败`
);
}
else
{
this
.
msg
.
success
(
`发送成功`
);
}
});
this
.
count
=
59
;
this
.
interval$
=
setInterval
(()
=>
{
this
.
count
-=
1
;
if
(
this
.
count
<=
0
)
{
clearInterval
(
this
.
interval$
);
}
this
.
cdr
.
detectChanges
();
},
1000
);
}
}
maxkey-web-frontend/maxkey-web-app/src/app/service/authn.service.ts
浏览文件 @
fe82cb8c
...
...
@@ -61,6 +61,10 @@ export class AuthnService {
return
this
.
http
.
post
(
'
/login/signin?_allow_anonymous=true
'
,
authParam
);
}
bindSocialsUser
(
authParam
:
any
)
{
return
this
.
http
.
post
(
'
/login/signin/bindusersocials?_allow_anonymous=true
'
,
authParam
);
}
//退出
logout
()
{
this
.
cookieService
.
delete
(
CONSTS
.
CONGRESS
,
'
/
'
);
...
...
maxkey-web-frontend/maxkey-web-app/src/app/service/socials-provider.service.ts
浏览文件 @
fe82cb8c
...
...
@@ -43,7 +43,15 @@ export class SocialsProviderService extends BaseService<SocialsProvider> {
return
this
.
getByParams
(
params
,
`/logon/oauth20/callback/
${
provider
}
?_allow_anonymous=true`
);
}
bindUser
(
provider
:
string
,
params
:
NzSafeAny
):
Observable
<
Message
<
SocialsProvider
>>
{
return
this
.
getByParams
(
params
,
`/logon/oauth20/binduser/
${
provider
}
?_allow_anonymous=true`
);
}
bind
(
provider
:
string
,
params
:
NzSafeAny
):
Observable
<
Message
<
SocialsProvider
>>
{
return
this
.
getByParams
(
params
,
`/logon/oauth20/bind/
${
provider
}
?_allow_anonymous=true`
);
}
qrcallback
(
provider
:
string
,
token
:
string
):
Observable
<
Message
<
SocialsProvider
>>
{
return
this
.
getByParams
({},
`/logon/oauth20/qrcallback/
${
provider
}
/
${
token
}
?_allow_anonymous=true`
);
}
}
maxkey-web-frontend/maxkey-web-app/src/assets/qrcode/qrcode.min.js
0 → 100644
浏览文件 @
fe82cb8c
/**
* @fileoverview
* - Using the 'QRCode for Javascript library'
* - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
* - this library has no dependencies.
*
* @author davidshimjs
* @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
* @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
*/
var
QRCode
;
(
function
()
{
//---------------------------------------------------------------------
// QRCode for JavaScript
//
// Copyright (c) 2009 Kazuhiko Arase
//
// URL: http://www.d-project.com/
//
// Licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// The word "QR Code" is registered trademark of
// DENSO WAVE INCORPORATED
// http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------
function
QR8bitByte
(
data
)
{
this
.
mode
=
QRMode
.
MODE_8BIT_BYTE
;
this
.
data
=
data
;
this
.
parsedData
=
[];
// Added to support UTF-8 Characters
for
(
var
i
=
0
,
l
=
this
.
data
.
length
;
i
<
l
;
i
++
)
{
var
byteArray
=
[];
var
code
=
this
.
data
.
charCodeAt
(
i
);
if
(
code
>
0x10000
)
{
byteArray
[
0
]
=
0xF0
|
((
code
&
0x1C0000
)
>>>
18
);
byteArray
[
1
]
=
0x80
|
((
code
&
0x3F000
)
>>>
12
);
byteArray
[
2
]
=
0x80
|
((
code
&
0xFC0
)
>>>
6
);
byteArray
[
3
]
=
0x80
|
(
code
&
0x3F
);
}
else
if
(
code
>
0x800
)
{
byteArray
[
0
]
=
0xE0
|
((
code
&
0xF000
)
>>>
12
);
byteArray
[
1
]
=
0x80
|
((
code
&
0xFC0
)
>>>
6
);
byteArray
[
2
]
=
0x80
|
(
code
&
0x3F
);
}
else
if
(
code
>
0x80
)
{
byteArray
[
0
]
=
0xC0
|
((
code
&
0x7C0
)
>>>
6
);
byteArray
[
1
]
=
0x80
|
(
code
&
0x3F
);
}
else
{
byteArray
[
0
]
=
code
;
}
this
.
parsedData
.
push
(
byteArray
);
}
this
.
parsedData
=
Array
.
prototype
.
concat
.
apply
([],
this
.
parsedData
);
if
(
this
.
parsedData
.
length
!=
this
.
data
.
length
)
{
this
.
parsedData
.
unshift
(
191
);
this
.
parsedData
.
unshift
(
187
);
this
.
parsedData
.
unshift
(
239
);
}
}
QR8bitByte
.
prototype
=
{
getLength
:
function
(
buffer
)
{
return
this
.
parsedData
.
length
;
},
write
:
function
(
buffer
)
{
for
(
var
i
=
0
,
l
=
this
.
parsedData
.
length
;
i
<
l
;
i
++
)
{
buffer
.
put
(
this
.
parsedData
[
i
],
8
);
}
}
};
function
QRCodeModel
(
typeNumber
,
errorCorrectLevel
)
{
this
.
typeNumber
=
typeNumber
;
this
.
errorCorrectLevel
=
errorCorrectLevel
;
this
.
modules
=
null
;
this
.
moduleCount
=
0
;
this
.
dataCache
=
null
;
this
.
dataList
=
[];
}
QRCodeModel
.
prototype
=
{
addData
:
function
(
data
){
var
newData
=
new
QR8bitByte
(
data
);
this
.
dataList
.
push
(
newData
);
this
.
dataCache
=
null
;},
isDark
:
function
(
row
,
col
){
if
(
row
<
0
||
this
.
moduleCount
<=
row
||
col
<
0
||
this
.
moduleCount
<=
col
){
throw
new
Error
(
row
+
"
,
"
+
col
);}
return
this
.
modules
[
row
][
col
];},
getModuleCount
:
function
(){
return
this
.
moduleCount
;},
make
:
function
(){
this
.
makeImpl
(
false
,
this
.
getBestMaskPattern
());},
makeImpl
:
function
(
test
,
maskPattern
){
this
.
moduleCount
=
this
.
typeNumber
*
4
+
17
;
this
.
modules
=
new
Array
(
this
.
moduleCount
);
for
(
var
row
=
0
;
row
<
this
.
moduleCount
;
row
++
){
this
.
modules
[
row
]
=
new
Array
(
this
.
moduleCount
);
for
(
var
col
=
0
;
col
<
this
.
moduleCount
;
col
++
){
this
.
modules
[
row
][
col
]
=
null
;}}
this
.
setupPositionProbePattern
(
0
,
0
);
this
.
setupPositionProbePattern
(
this
.
moduleCount
-
7
,
0
);
this
.
setupPositionProbePattern
(
0
,
this
.
moduleCount
-
7
);
this
.
setupPositionAdjustPattern
();
this
.
setupTimingPattern
();
this
.
setupTypeInfo
(
test
,
maskPattern
);
if
(
this
.
typeNumber
>=
7
){
this
.
setupTypeNumber
(
test
);}
if
(
this
.
dataCache
==
null
){
this
.
dataCache
=
QRCodeModel
.
createData
(
this
.
typeNumber
,
this
.
errorCorrectLevel
,
this
.
dataList
);}
this
.
mapData
(
this
.
dataCache
,
maskPattern
);},
setupPositionProbePattern
:
function
(
row
,
col
){
for
(
var
r
=-
1
;
r
<=
7
;
r
++
){
if
(
row
+
r
<=-
1
||
this
.
moduleCount
<=
row
+
r
)
continue
;
for
(
var
c
=-
1
;
c
<=
7
;
c
++
){
if
(
col
+
c
<=-
1
||
this
.
moduleCount
<=
col
+
c
)
continue
;
if
((
0
<=
r
&&
r
<=
6
&&
(
c
==
0
||
c
==
6
))
||
(
0
<=
c
&&
c
<=
6
&&
(
r
==
0
||
r
==
6
))
||
(
2
<=
r
&&
r
<=
4
&&
2
<=
c
&&
c
<=
4
)){
this
.
modules
[
row
+
r
][
col
+
c
]
=
true
;}
else
{
this
.
modules
[
row
+
r
][
col
+
c
]
=
false
;}}}},
getBestMaskPattern
:
function
(){
var
minLostPoint
=
0
;
var
pattern
=
0
;
for
(
var
i
=
0
;
i
<
8
;
i
++
){
this
.
makeImpl
(
true
,
i
);
var
lostPoint
=
QRUtil
.
getLostPoint
(
this
);
if
(
i
==
0
||
minLostPoint
>
lostPoint
){
minLostPoint
=
lostPoint
;
pattern
=
i
;}}
return
pattern
;},
createMovieClip
:
function
(
target_mc
,
instance_name
,
depth
){
var
qr_mc
=
target_mc
.
createEmptyMovieClip
(
instance_name
,
depth
);
var
cs
=
1
;
this
.
make
();
for
(
var
row
=
0
;
row
<
this
.
modules
.
length
;
row
++
){
var
y
=
row
*
cs
;
for
(
var
col
=
0
;
col
<
this
.
modules
[
row
].
length
;
col
++
){
var
x
=
col
*
cs
;
var
dark
=
this
.
modules
[
row
][
col
];
if
(
dark
){
qr_mc
.
beginFill
(
0
,
100
);
qr_mc
.
moveTo
(
x
,
y
);
qr_mc
.
lineTo
(
x
+
cs
,
y
);
qr_mc
.
lineTo
(
x
+
cs
,
y
+
cs
);
qr_mc
.
lineTo
(
x
,
y
+
cs
);
qr_mc
.
endFill
();}}}
return
qr_mc
;},
setupTimingPattern
:
function
(){
for
(
var
r
=
8
;
r
<
this
.
moduleCount
-
8
;
r
++
){
if
(
this
.
modules
[
r
][
6
]
!=
null
){
continue
;}
this
.
modules
[
r
][
6
]
=
(
r
%
2
==
0
);}
for
(
var
c
=
8
;
c
<
this
.
moduleCount
-
8
;
c
++
){
if
(
this
.
modules
[
6
][
c
]
!=
null
){
continue
;}
this
.
modules
[
6
][
c
]
=
(
c
%
2
==
0
);}},
setupPositionAdjustPattern
:
function
(){
var
pos
=
QRUtil
.
getPatternPosition
(
this
.
typeNumber
);
for
(
var
i
=
0
;
i
<
pos
.
length
;
i
++
){
for
(
var
j
=
0
;
j
<
pos
.
length
;
j
++
){
var
row
=
pos
[
i
];
var
col
=
pos
[
j
];
if
(
this
.
modules
[
row
][
col
]
!=
null
){
continue
;}
for
(
var
r
=-
2
;
r
<=
2
;
r
++
){
for
(
var
c
=-
2
;
c
<=
2
;
c
++
){
if
(
r
==-
2
||
r
==
2
||
c
==-
2
||
c
==
2
||
(
r
==
0
&&
c
==
0
)){
this
.
modules
[
row
+
r
][
col
+
c
]
=
true
;}
else
{
this
.
modules
[
row
+
r
][
col
+
c
]
=
false
;}}}}}},
setupTypeNumber
:
function
(
test
){
var
bits
=
QRUtil
.
getBCHTypeNumber
(
this
.
typeNumber
);
for
(
var
i
=
0
;
i
<
18
;
i
++
){
var
mod
=
(
!
test
&&
((
bits
>>
i
)
&
1
)
==
1
);
this
.
modules
[
Math
.
floor
(
i
/
3
)][
i
%
3
+
this
.
moduleCount
-
8
-
3
]
=
mod
;}
for
(
var
i
=
0
;
i
<
18
;
i
++
){
var
mod
=
(
!
test
&&
((
bits
>>
i
)
&
1
)
==
1
);
this
.
modules
[
i
%
3
+
this
.
moduleCount
-
8
-
3
][
Math
.
floor
(
i
/
3
)]
=
mod
;}},
setupTypeInfo
:
function
(
test
,
maskPattern
){
var
data
=
(
this
.
errorCorrectLevel
<<
3
)
|
maskPattern
;
var
bits
=
QRUtil
.
getBCHTypeInfo
(
data
);
for
(
var
i
=
0
;
i
<
15
;
i
++
){
var
mod
=
(
!
test
&&
((
bits
>>
i
)
&
1
)
==
1
);
if
(
i
<
6
){
this
.
modules
[
i
][
8
]
=
mod
;}
else
if
(
i
<
8
){
this
.
modules
[
i
+
1
][
8
]
=
mod
;}
else
{
this
.
modules
[
this
.
moduleCount
-
15
+
i
][
8
]
=
mod
;}}
for
(
var
i
=
0
;
i
<
15
;
i
++
){
var
mod
=
(
!
test
&&
((
bits
>>
i
)
&
1
)
==
1
);
if
(
i
<
8
){
this
.
modules
[
8
][
this
.
moduleCount
-
i
-
1
]
=
mod
;}
else
if
(
i
<
9
){
this
.
modules
[
8
][
15
-
i
-
1
+
1
]
=
mod
;}
else
{
this
.
modules
[
8
][
15
-
i
-
1
]
=
mod
;}}
this
.
modules
[
this
.
moduleCount
-
8
][
8
]
=
(
!
test
);},
mapData
:
function
(
data
,
maskPattern
){
var
inc
=-
1
;
var
row
=
this
.
moduleCount
-
1
;
var
bitIndex
=
7
;
var
byteIndex
=
0
;
for
(
var
col
=
this
.
moduleCount
-
1
;
col
>
0
;
col
-=
2
){
if
(
col
==
6
)
col
--
;
while
(
true
){
for
(
var
c
=
0
;
c
<
2
;
c
++
){
if
(
this
.
modules
[
row
][
col
-
c
]
==
null
){
var
dark
=
false
;
if
(
byteIndex
<
data
.
length
){
dark
=
(((
data
[
byteIndex
]
>>>
bitIndex
)
&
1
)
==
1
);}
var
mask
=
QRUtil
.
getMask
(
maskPattern
,
row
,
col
-
c
);
if
(
mask
){
dark
=!
dark
;}
this
.
modules
[
row
][
col
-
c
]
=
dark
;
bitIndex
--
;
if
(
bitIndex
==-
1
){
byteIndex
++
;
bitIndex
=
7
;}}}
row
+=
inc
;
if
(
row
<
0
||
this
.
moduleCount
<=
row
){
row
-=
inc
;
inc
=-
inc
;
break
;}}}}};
QRCodeModel
.
PAD0
=
0xEC
;
QRCodeModel
.
PAD1
=
0x11
;
QRCodeModel
.
createData
=
function
(
typeNumber
,
errorCorrectLevel
,
dataList
){
var
rsBlocks
=
QRRSBlock
.
getRSBlocks
(
typeNumber
,
errorCorrectLevel
);
var
buffer
=
new
QRBitBuffer
();
for
(
var
i
=
0
;
i
<
dataList
.
length
;
i
++
){
var
data
=
dataList
[
i
];
buffer
.
put
(
data
.
mode
,
4
);
buffer
.
put
(
data
.
getLength
(),
QRUtil
.
getLengthInBits
(
data
.
mode
,
typeNumber
));
data
.
write
(
buffer
);}
var
totalDataCount
=
0
;
for
(
var
i
=
0
;
i
<
rsBlocks
.
length
;
i
++
){
totalDataCount
+=
rsBlocks
[
i
].
dataCount
;}
if
(
buffer
.
getLengthInBits
()
>
totalDataCount
*
8
){
throw
new
Error
(
"
code length overflow. (
"
+
buffer
.
getLengthInBits
()
+
"
>
"
+
totalDataCount
*
8
+
"
)
"
);}
if
(
buffer
.
getLengthInBits
()
+
4
<=
totalDataCount
*
8
){
buffer
.
put
(
0
,
4
);}
while
(
buffer
.
getLengthInBits
()
%
8
!=
0
){
buffer
.
putBit
(
false
);}
while
(
true
){
if
(
buffer
.
getLengthInBits
()
>=
totalDataCount
*
8
){
break
;}
buffer
.
put
(
QRCodeModel
.
PAD0
,
8
);
if
(
buffer
.
getLengthInBits
()
>=
totalDataCount
*
8
){
break
;}
buffer
.
put
(
QRCodeModel
.
PAD1
,
8
);}
return
QRCodeModel
.
createBytes
(
buffer
,
rsBlocks
);};
QRCodeModel
.
createBytes
=
function
(
buffer
,
rsBlocks
){
var
offset
=
0
;
var
maxDcCount
=
0
;
var
maxEcCount
=
0
;
var
dcdata
=
new
Array
(
rsBlocks
.
length
);
var
ecdata
=
new
Array
(
rsBlocks
.
length
);
for
(
var
r
=
0
;
r
<
rsBlocks
.
length
;
r
++
){
var
dcCount
=
rsBlocks
[
r
].
dataCount
;
var
ecCount
=
rsBlocks
[
r
].
totalCount
-
dcCount
;
maxDcCount
=
Math
.
max
(
maxDcCount
,
dcCount
);
maxEcCount
=
Math
.
max
(
maxEcCount
,
ecCount
);
dcdata
[
r
]
=
new
Array
(
dcCount
);
for
(
var
i
=
0
;
i
<
dcdata
[
r
].
length
;
i
++
){
dcdata
[
r
][
i
]
=
0xff
&
buffer
.
buffer
[
i
+
offset
];}
offset
+=
dcCount
;
var
rsPoly
=
QRUtil
.
getErrorCorrectPolynomial
(
ecCount
);
var
rawPoly
=
new
QRPolynomial
(
dcdata
[
r
],
rsPoly
.
getLength
()
-
1
);
var
modPoly
=
rawPoly
.
mod
(
rsPoly
);
ecdata
[
r
]
=
new
Array
(
rsPoly
.
getLength
()
-
1
);
for
(
var
i
=
0
;
i
<
ecdata
[
r
].
length
;
i
++
){
var
modIndex
=
i
+
modPoly
.
getLength
()
-
ecdata
[
r
].
length
;
ecdata
[
r
][
i
]
=
(
modIndex
>=
0
)?
modPoly
.
get
(
modIndex
):
0
;}}
var
totalCodeCount
=
0
;
for
(
var
i
=
0
;
i
<
rsBlocks
.
length
;
i
++
){
totalCodeCount
+=
rsBlocks
[
i
].
totalCount
;}
var
data
=
new
Array
(
totalCodeCount
);
var
index
=
0
;
for
(
var
i
=
0
;
i
<
maxDcCount
;
i
++
){
for
(
var
r
=
0
;
r
<
rsBlocks
.
length
;
r
++
){
if
(
i
<
dcdata
[
r
].
length
){
data
[
index
++
]
=
dcdata
[
r
][
i
];}}}
for
(
var
i
=
0
;
i
<
maxEcCount
;
i
++
){
for
(
var
r
=
0
;
r
<
rsBlocks
.
length
;
r
++
){
if
(
i
<
ecdata
[
r
].
length
){
data
[
index
++
]
=
ecdata
[
r
][
i
];}}}
return
data
;};
var
QRMode
=
{
MODE_NUMBER
:
1
<<
0
,
MODE_ALPHA_NUM
:
1
<<
1
,
MODE_8BIT_BYTE
:
1
<<
2
,
MODE_KANJI
:
1
<<
3
};
var
QRErrorCorrectLevel
=
{
L
:
1
,
M
:
0
,
Q
:
3
,
H
:
2
};
var
QRMaskPattern
=
{
PATTERN000
:
0
,
PATTERN001
:
1
,
PATTERN010
:
2
,
PATTERN011
:
3
,
PATTERN100
:
4
,
PATTERN101
:
5
,
PATTERN110
:
6
,
PATTERN111
:
7
};
var
QRUtil
=
{
PATTERN_POSITION_TABLE
:[[],[
6
,
18
],[
6
,
22
],[
6
,
26
],[
6
,
30
],[
6
,
34
],[
6
,
22
,
38
],[
6
,
24
,
42
],[
6
,
26
,
46
],[
6
,
28
,
50
],[
6
,
30
,
54
],[
6
,
32
,
58
],[
6
,
34
,
62
],[
6
,
26
,
46
,
66
],[
6
,
26
,
48
,
70
],[
6
,
26
,
50
,
74
],[
6
,
30
,
54
,
78
],[
6
,
30
,
56
,
82
],[
6
,
30
,
58
,
86
],[
6
,
34
,
62
,
90
],[
6
,
28
,
50
,
72
,
94
],[
6
,
26
,
50
,
74
,
98
],[
6
,
30
,
54
,
78
,
102
],[
6
,
28
,
54
,
80
,
106
],[
6
,
32
,
58
,
84
,
110
],[
6
,
30
,
58
,
86
,
114
],[
6
,
34
,
62
,
90
,
118
],[
6
,
26
,
50
,
74
,
98
,
122
],[
6
,
30
,
54
,
78
,
102
,
126
],[
6
,
26
,
52
,
78
,
104
,
130
],[
6
,
30
,
56
,
82
,
108
,
134
],[
6
,
34
,
60
,
86
,
112
,
138
],[
6
,
30
,
58
,
86
,
114
,
142
],[
6
,
34
,
62
,
90
,
118
,
146
],[
6
,
30
,
54
,
78
,
102
,
126
,
150
],[
6
,
24
,
50
,
76
,
102
,
128
,
154
],[
6
,
28
,
54
,
80
,
106
,
132
,
158
],[
6
,
32
,
58
,
84
,
110
,
136
,
162
],[
6
,
26
,
54
,
82
,
110
,
138
,
166
],[
6
,
30
,
58
,
86
,
114
,
142
,
170
]],
G15
:(
1
<<
10
)
|
(
1
<<
8
)
|
(
1
<<
5
)
|
(
1
<<
4
)
|
(
1
<<
2
)
|
(
1
<<
1
)
|
(
1
<<
0
),
G18
:(
1
<<
12
)
|
(
1
<<
11
)
|
(
1
<<
10
)
|
(
1
<<
9
)
|
(
1
<<
8
)
|
(
1
<<
5
)
|
(
1
<<
2
)
|
(
1
<<
0
),
G15_MASK
:(
1
<<
14
)
|
(
1
<<
12
)
|
(
1
<<
10
)
|
(
1
<<
4
)
|
(
1
<<
1
),
getBCHTypeInfo
:
function
(
data
){
var
d
=
data
<<
10
;
while
(
QRUtil
.
getBCHDigit
(
d
)
-
QRUtil
.
getBCHDigit
(
QRUtil
.
G15
)
>=
0
){
d
^=
(
QRUtil
.
G15
<<
(
QRUtil
.
getBCHDigit
(
d
)
-
QRUtil
.
getBCHDigit
(
QRUtil
.
G15
)));}
return
((
data
<<
10
)
|
d
)
^
QRUtil
.
G15_MASK
;},
getBCHTypeNumber
:
function
(
data
){
var
d
=
data
<<
12
;
while
(
QRUtil
.
getBCHDigit
(
d
)
-
QRUtil
.
getBCHDigit
(
QRUtil
.
G18
)
>=
0
){
d
^=
(
QRUtil
.
G18
<<
(
QRUtil
.
getBCHDigit
(
d
)
-
QRUtil
.
getBCHDigit
(
QRUtil
.
G18
)));}
return
(
data
<<
12
)
|
d
;},
getBCHDigit
:
function
(
data
){
var
digit
=
0
;
while
(
data
!=
0
){
digit
++
;
data
>>>=
1
;}
return
digit
;},
getPatternPosition
:
function
(
typeNumber
){
return
QRUtil
.
PATTERN_POSITION_TABLE
[
typeNumber
-
1
];},
getMask
:
function
(
maskPattern
,
i
,
j
){
switch
(
maskPattern
){
case
QRMaskPattern
.
PATTERN000
:
return
(
i
+
j
)
%
2
==
0
;
case
QRMaskPattern
.
PATTERN001
:
return
i
%
2
==
0
;
case
QRMaskPattern
.
PATTERN010
:
return
j
%
3
==
0
;
case
QRMaskPattern
.
PATTERN011
:
return
(
i
+
j
)
%
3
==
0
;
case
QRMaskPattern
.
PATTERN100
:
return
(
Math
.
floor
(
i
/
2
)
+
Math
.
floor
(
j
/
3
))
%
2
==
0
;
case
QRMaskPattern
.
PATTERN101
:
return
(
i
*
j
)
%
2
+
(
i
*
j
)
%
3
==
0
;
case
QRMaskPattern
.
PATTERN110
:
return
((
i
*
j
)
%
2
+
(
i
*
j
)
%
3
)
%
2
==
0
;
case
QRMaskPattern
.
PATTERN111
:
return
((
i
*
j
)
%
3
+
(
i
+
j
)
%
2
)
%
2
==
0
;
default
:
throw
new
Error
(
"
bad maskPattern:
"
+
maskPattern
);}},
getErrorCorrectPolynomial
:
function
(
errorCorrectLength
){
var
a
=
new
QRPolynomial
([
1
],
0
);
for
(
var
i
=
0
;
i
<
errorCorrectLength
;
i
++
){
a
=
a
.
multiply
(
new
QRPolynomial
([
1
,
QRMath
.
gexp
(
i
)],
0
));}
return
a
;},
getLengthInBits
:
function
(
mode
,
type
){
if
(
1
<=
type
&&
type
<
10
){
switch
(
mode
){
case
QRMode
.
MODE_NUMBER
:
return
10
;
case
QRMode
.
MODE_ALPHA_NUM
:
return
9
;
case
QRMode
.
MODE_8BIT_BYTE
:
return
8
;
case
QRMode
.
MODE_KANJI
:
return
8
;
default
:
throw
new
Error
(
"
mode:
"
+
mode
);}}
else
if
(
type
<
27
){
switch
(
mode
){
case
QRMode
.
MODE_NUMBER
:
return
12
;
case
QRMode
.
MODE_ALPHA_NUM
:
return
11
;
case
QRMode
.
MODE_8BIT_BYTE
:
return
16
;
case
QRMode
.
MODE_KANJI
:
return
10
;
default
:
throw
new
Error
(
"
mode:
"
+
mode
);}}
else
if
(
type
<
41
){
switch
(
mode
){
case
QRMode
.
MODE_NUMBER
:
return
14
;
case
QRMode
.
MODE_ALPHA_NUM
:
return
13
;
case
QRMode
.
MODE_8BIT_BYTE
:
return
16
;
case
QRMode
.
MODE_KANJI
:
return
12
;
default
:
throw
new
Error
(
"
mode:
"
+
mode
);}}
else
{
throw
new
Error
(
"
type:
"
+
type
);}},
getLostPoint
:
function
(
qrCode
){
var
moduleCount
=
qrCode
.
getModuleCount
();
var
lostPoint
=
0
;
for
(
var
row
=
0
;
row
<
moduleCount
;
row
++
){
for
(
var
col
=
0
;
col
<
moduleCount
;
col
++
){
var
sameCount
=
0
;
var
dark
=
qrCode
.
isDark
(
row
,
col
);
for
(
var
r
=-
1
;
r
<=
1
;
r
++
){
if
(
row
+
r
<
0
||
moduleCount
<=
row
+
r
){
continue
;}
for
(
var
c
=-
1
;
c
<=
1
;
c
++
){
if
(
col
+
c
<
0
||
moduleCount
<=
col
+
c
){
continue
;}
if
(
r
==
0
&&
c
==
0
){
continue
;}
if
(
dark
==
qrCode
.
isDark
(
row
+
r
,
col
+
c
)){
sameCount
++
;}}}
if
(
sameCount
>
5
){
lostPoint
+=
(
3
+
sameCount
-
5
);}}}
for
(
var
row
=
0
;
row
<
moduleCount
-
1
;
row
++
){
for
(
var
col
=
0
;
col
<
moduleCount
-
1
;
col
++
){
var
count
=
0
;
if
(
qrCode
.
isDark
(
row
,
col
))
count
++
;
if
(
qrCode
.
isDark
(
row
+
1
,
col
))
count
++
;
if
(
qrCode
.
isDark
(
row
,
col
+
1
))
count
++
;
if
(
qrCode
.
isDark
(
row
+
1
,
col
+
1
))
count
++
;
if
(
count
==
0
||
count
==
4
){
lostPoint
+=
3
;}}}
for
(
var
row
=
0
;
row
<
moduleCount
;
row
++
){
for
(
var
col
=
0
;
col
<
moduleCount
-
6
;
col
++
){
if
(
qrCode
.
isDark
(
row
,
col
)
&&!
qrCode
.
isDark
(
row
,
col
+
1
)
&&
qrCode
.
isDark
(
row
,
col
+
2
)
&&
qrCode
.
isDark
(
row
,
col
+
3
)
&&
qrCode
.
isDark
(
row
,
col
+
4
)
&&!
qrCode
.
isDark
(
row
,
col
+
5
)
&&
qrCode
.
isDark
(
row
,
col
+
6
)){
lostPoint
+=
40
;}}}
for
(
var
col
=
0
;
col
<
moduleCount
;
col
++
){
for
(
var
row
=
0
;
row
<
moduleCount
-
6
;
row
++
){
if
(
qrCode
.
isDark
(
row
,
col
)
&&!
qrCode
.
isDark
(
row
+
1
,
col
)
&&
qrCode
.
isDark
(
row
+
2
,
col
)
&&
qrCode
.
isDark
(
row
+
3
,
col
)
&&
qrCode
.
isDark
(
row
+
4
,
col
)
&&!
qrCode
.
isDark
(
row
+
5
,
col
)
&&
qrCode
.
isDark
(
row
+
6
,
col
)){
lostPoint
+=
40
;}}}
var
darkCount
=
0
;
for
(
var
col
=
0
;
col
<
moduleCount
;
col
++
){
for
(
var
row
=
0
;
row
<
moduleCount
;
row
++
){
if
(
qrCode
.
isDark
(
row
,
col
)){
darkCount
++
;}}}
var
ratio
=
Math
.
abs
(
100
*
darkCount
/
moduleCount
/
moduleCount
-
50
)
/
5
;
lostPoint
+=
ratio
*
10
;
return
lostPoint
;}};
var
QRMath
=
{
glog
:
function
(
n
){
if
(
n
<
1
){
throw
new
Error
(
"
glog(
"
+
n
+
"
)
"
);}
return
QRMath
.
LOG_TABLE
[
n
];},
gexp
:
function
(
n
){
while
(
n
<
0
){
n
+=
255
;}
while
(
n
>=
256
){
n
-=
255
;}
return
QRMath
.
EXP_TABLE
[
n
];},
EXP_TABLE
:
new
Array
(
256
),
LOG_TABLE
:
new
Array
(
256
)};
for
(
var
i
=
0
;
i
<
8
;
i
++
){
QRMath
.
EXP_TABLE
[
i
]
=
1
<<
i
;}
for
(
var
i
=
8
;
i
<
256
;
i
++
){
QRMath
.
EXP_TABLE
[
i
]
=
QRMath
.
EXP_TABLE
[
i
-
4
]
^
QRMath
.
EXP_TABLE
[
i
-
5
]
^
QRMath
.
EXP_TABLE
[
i
-
6
]
^
QRMath
.
EXP_TABLE
[
i
-
8
];}
for
(
var
i
=
0
;
i
<
255
;
i
++
){
QRMath
.
LOG_TABLE
[
QRMath
.
EXP_TABLE
[
i
]]
=
i
;}
function
QRPolynomial
(
num
,
shift
){
if
(
num
.
length
==
undefined
){
throw
new
Error
(
num
.
length
+
"
/
"
+
shift
);}
var
offset
=
0
;
while
(
offset
<
num
.
length
&&
num
[
offset
]
==
0
){
offset
++
;}
this
.
num
=
new
Array
(
num
.
length
-
offset
+
shift
);
for
(
var
i
=
0
;
i
<
num
.
length
-
offset
;
i
++
){
this
.
num
[
i
]
=
num
[
i
+
offset
];}}
QRPolynomial
.
prototype
=
{
get
:
function
(
index
){
return
this
.
num
[
index
];},
getLength
:
function
(){
return
this
.
num
.
length
;},
multiply
:
function
(
e
){
var
num
=
new
Array
(
this
.
getLength
()
+
e
.
getLength
()
-
1
);
for
(
var
i
=
0
;
i
<
this
.
getLength
();
i
++
){
for
(
var
j
=
0
;
j
<
e
.
getLength
();
j
++
){
num
[
i
+
j
]
^=
QRMath
.
gexp
(
QRMath
.
glog
(
this
.
get
(
i
))
+
QRMath
.
glog
(
e
.
get
(
j
)));}}
return
new
QRPolynomial
(
num
,
0
);},
mod
:
function
(
e
){
if
(
this
.
getLength
()
-
e
.
getLength
()
<
0
){
return
this
;}
var
ratio
=
QRMath
.
glog
(
this
.
get
(
0
))
-
QRMath
.
glog
(
e
.
get
(
0
));
var
num
=
new
Array
(
this
.
getLength
());
for
(
var
i
=
0
;
i
<
this
.
getLength
();
i
++
){
num
[
i
]
=
this
.
get
(
i
);}
for
(
var
i
=
0
;
i
<
e
.
getLength
();
i
++
){
num
[
i
]
^=
QRMath
.
gexp
(
QRMath
.
glog
(
e
.
get
(
i
))
+
ratio
);}
return
new
QRPolynomial
(
num
,
0
).
mod
(
e
);}};
function
QRRSBlock
(
totalCount
,
dataCount
){
this
.
totalCount
=
totalCount
;
this
.
dataCount
=
dataCount
;}
QRRSBlock
.
RS_BLOCK_TABLE
=
[[
1
,
26
,
19
],[
1
,
26
,
16
],[
1
,
26
,
13
],[
1
,
26
,
9
],[
1
,
44
,
34
],[
1
,
44
,
28
],[
1
,
44
,
22
],[
1
,
44
,
16
],[
1
,
70
,
55
],[
1
,
70
,
44
],[
2
,
35
,
17
],[
2
,
35
,
13
],[
1
,
100
,
80
],[
2
,
50
,
32
],[
2
,
50
,
24
],[
4
,
25
,
9
],[
1
,
134
,
108
],[
2
,
67
,
43
],[
2
,
33
,
15
,
2
,
34
,
16
],[
2
,
33
,
11
,
2
,
34
,
12
],[
2
,
86
,
68
],[
4
,
43
,
27
],[
4
,
43
,
19
],[
4
,
43
,
15
],[
2
,
98
,
78
],[
4
,
49
,
31
],[
2
,
32
,
14
,
4
,
33
,
15
],[
4
,
39
,
13
,
1
,
40
,
14
],[
2
,
121
,
97
],[
2
,
60
,
38
,
2
,
61
,
39
],[
4
,
40
,
18
,
2
,
41
,
19
],[
4
,
40
,
14
,
2
,
41
,
15
],[
2
,
146
,
116
],[
3
,
58
,
36
,
2
,
59
,
37
],[
4
,
36
,
16
,
4
,
37
,
17
],[
4
,
36
,
12
,
4
,
37
,
13
],[
2
,
86
,
68
,
2
,
87
,
69
],[
4
,
69
,
43
,
1
,
70
,
44
],[
6
,
43
,
19
,
2
,
44
,
20
],[
6
,
43
,
15
,
2
,
44
,
16
],[
4
,
101
,
81
],[
1
,
80
,
50
,
4
,
81
,
51
],[
4
,
50
,
22
,
4
,
51
,
23
],[
3
,
36
,
12
,
8
,
37
,
13
],[
2
,
116
,
92
,
2
,
117
,
93
],[
6
,
58
,
36
,
2
,
59
,
37
],[
4
,
46
,
20
,
6
,
47
,
21
],[
7
,
42
,
14
,
4
,
43
,
15
],[
4
,
133
,
107
],[
8
,
59
,
37
,
1
,
60
,
38
],[
8
,
44
,
20
,
4
,
45
,
21
],[
12
,
33
,
11
,
4
,
34
,
12
],[
3
,
145
,
115
,
1
,
146
,
116
],[
4
,
64
,
40
,
5
,
65
,
41
],[
11
,
36
,
16
,
5
,
37
,
17
],[
11
,
36
,
12
,
5
,
37
,
13
],[
5
,
109
,
87
,
1
,
110
,
88
],[
5
,
65
,
41
,
5
,
66
,
42
],[
5
,
54
,
24
,
7
,
55
,
25
],[
11
,
36
,
12
],[
5
,
122
,
98
,
1
,
123
,
99
],[
7
,
73
,
45
,
3
,
74
,
46
],[
15
,
43
,
19
,
2
,
44
,
20
],[
3
,
45
,
15
,
13
,
46
,
16
],[
1
,
135
,
107
,
5
,
136
,
108
],[
10
,
74
,
46
,
1
,
75
,
47
],[
1
,
50
,
22
,
15
,
51
,
23
],[
2
,
42
,
14
,
17
,
43
,
15
],[
5
,
150
,
120
,
1
,
151
,
121
],[
9
,
69
,
43
,
4
,
70
,
44
],[
17
,
50
,
22
,
1
,
51
,
23
],[
2
,
42
,
14
,
19
,
43
,
15
],[
3
,
141
,
113
,
4
,
142
,
114
],[
3
,
70
,
44
,
11
,
71
,
45
],[
17
,
47
,
21
,
4
,
48
,
22
],[
9
,
39
,
13
,
16
,
40
,
14
],[
3
,
135
,
107
,
5
,
136
,
108
],[
3
,
67
,
41
,
13
,
68
,
42
],[
15
,
54
,
24
,
5
,
55
,
25
],[
15
,
43
,
15
,
10
,
44
,
16
],[
4
,
144
,
116
,
4
,
145
,
117
],[
17
,
68
,
42
],[
17
,
50
,
22
,
6
,
51
,
23
],[
19
,
46
,
16
,
6
,
47
,
17
],[
2
,
139
,
111
,
7
,
140
,
112
],[
17
,
74
,
46
],[
7
,
54
,
24
,
16
,
55
,
25
],[
34
,
37
,
13
],[
4
,
151
,
121
,
5
,
152
,
122
],[
4
,
75
,
47
,
14
,
76
,
48
],[
11
,
54
,
24
,
14
,
55
,
25
],[
16
,
45
,
15
,
14
,
46
,
16
],[
6
,
147
,
117
,
4
,
148
,
118
],[
6
,
73
,
45
,
14
,
74
,
46
],[
11
,
54
,
24
,
16
,
55
,
25
],[
30
,
46
,
16
,
2
,
47
,
17
],[
8
,
132
,
106
,
4
,
133
,
107
],[
8
,
75
,
47
,
13
,
76
,
48
],[
7
,
54
,
24
,
22
,
55
,
25
],[
22
,
45
,
15
,
13
,
46
,
16
],[
10
,
142
,
114
,
2
,
143
,
115
],[
19
,
74
,
46
,
4
,
75
,
47
],[
28
,
50
,
22
,
6
,
51
,
23
],[
33
,
46
,
16
,
4
,
47
,
17
],[
8
,
152
,
122
,
4
,
153
,
123
],[
22
,
73
,
45
,
3
,
74
,
46
],[
8
,
53
,
23
,
26
,
54
,
24
],[
12
,
45
,
15
,
28
,
46
,
16
],[
3
,
147
,
117
,
10
,
148
,
118
],[
3
,
73
,
45
,
23
,
74
,
46
],[
4
,
54
,
24
,
31
,
55
,
25
],[
11
,
45
,
15
,
31
,
46
,
16
],[
7
,
146
,
116
,
7
,
147
,
117
],[
21
,
73
,
45
,
7
,
74
,
46
],[
1
,
53
,
23
,
37
,
54
,
24
],[
19
,
45
,
15
,
26
,
46
,
16
],[
5
,
145
,
115
,
10
,
146
,
116
],[
19
,
75
,
47
,
10
,
76
,
48
],[
15
,
54
,
24
,
25
,
55
,
25
],[
23
,
45
,
15
,
25
,
46
,
16
],[
13
,
145
,
115
,
3
,
146
,
116
],[
2
,
74
,
46
,
29
,
75
,
47
],[
42
,
54
,
24
,
1
,
55
,
25
],[
23
,
45
,
15
,
28
,
46
,
16
],[
17
,
145
,
115
],[
10
,
74
,
46
,
23
,
75
,
47
],[
10
,
54
,
24
,
35
,
55
,
25
],[
19
,
45
,
15
,
35
,
46
,
16
],[
17
,
145
,
115
,
1
,
146
,
116
],[
14
,
74
,
46
,
21
,
75
,
47
],[
29
,
54
,
24
,
19
,
55
,
25
],[
11
,
45
,
15
,
46
,
46
,
16
],[
13
,
145
,
115
,
6
,
146
,
116
],[
14
,
74
,
46
,
23
,
75
,
47
],[
44
,
54
,
24
,
7
,
55
,
25
],[
59
,
46
,
16
,
1
,
47
,
17
],[
12
,
151
,
121
,
7
,
152
,
122
],[
12
,
75
,
47
,
26
,
76
,
48
],[
39
,
54
,
24
,
14
,
55
,
25
],[
22
,
45
,
15
,
41
,
46
,
16
],[
6
,
151
,
121
,
14
,
152
,
122
],[
6
,
75
,
47
,
34
,
76
,
48
],[
46
,
54
,
24
,
10
,
55
,
25
],[
2
,
45
,
15
,
64
,
46
,
16
],[
17
,
152
,
122
,
4
,
153
,
123
],[
29
,
74
,
46
,
14
,
75
,
47
],[
49
,
54
,
24
,
10
,
55
,
25
],[
24
,
45
,
15
,
46
,
46
,
16
],[
4
,
152
,
122
,
18
,
153
,
123
],[
13
,
74
,
46
,
32
,
75
,
47
],[
48
,
54
,
24
,
14
,
55
,
25
],[
42
,
45
,
15
,
32
,
46
,
16
],[
20
,
147
,
117
,
4
,
148
,
118
],[
40
,
75
,
47
,
7
,
76
,
48
],[
43
,
54
,
24
,
22
,
55
,
25
],[
10
,
45
,
15
,
67
,
46
,
16
],[
19
,
148
,
118
,
6
,
149
,
119
],[
18
,
75
,
47
,
31
,
76
,
48
],[
34
,
54
,
24
,
34
,
55
,
25
],[
20
,
45
,
15
,
61
,
46
,
16
]];
QRRSBlock
.
getRSBlocks
=
function
(
typeNumber
,
errorCorrectLevel
){
var
rsBlock
=
QRRSBlock
.
getRsBlockTable
(
typeNumber
,
errorCorrectLevel
);
if
(
rsBlock
==
undefined
){
throw
new
Error
(
"
bad rs block @ typeNumber:
"
+
typeNumber
+
"
/errorCorrectLevel:
"
+
errorCorrectLevel
);}
var
length
=
rsBlock
.
length
/
3
;
var
list
=
[];
for
(
var
i
=
0
;
i
<
length
;
i
++
){
var
count
=
rsBlock
[
i
*
3
+
0
];
var
totalCount
=
rsBlock
[
i
*
3
+
1
];
var
dataCount
=
rsBlock
[
i
*
3
+
2
];
for
(
var
j
=
0
;
j
<
count
;
j
++
){
list
.
push
(
new
QRRSBlock
(
totalCount
,
dataCount
));}}
return
list
;};
QRRSBlock
.
getRsBlockTable
=
function
(
typeNumber
,
errorCorrectLevel
){
switch
(
errorCorrectLevel
){
case
QRErrorCorrectLevel
.
L
:
return
QRRSBlock
.
RS_BLOCK_TABLE
[(
typeNumber
-
1
)
*
4
+
0
];
case
QRErrorCorrectLevel
.
M
:
return
QRRSBlock
.
RS_BLOCK_TABLE
[(
typeNumber
-
1
)
*
4
+
1
];
case
QRErrorCorrectLevel
.
Q
:
return
QRRSBlock
.
RS_BLOCK_TABLE
[(
typeNumber
-
1
)
*
4
+
2
];
case
QRErrorCorrectLevel
.
H
:
return
QRRSBlock
.
RS_BLOCK_TABLE
[(
typeNumber
-
1
)
*
4
+
3
];
default
:
return
undefined
;}};
function
QRBitBuffer
(){
this
.
buffer
=
[];
this
.
length
=
0
;}
QRBitBuffer
.
prototype
=
{
get
:
function
(
index
){
var
bufIndex
=
Math
.
floor
(
index
/
8
);
return
((
this
.
buffer
[
bufIndex
]
>>>
(
7
-
index
%
8
))
&
1
)
==
1
;},
put
:
function
(
num
,
length
){
for
(
var
i
=
0
;
i
<
length
;
i
++
){
this
.
putBit
(((
num
>>>
(
length
-
i
-
1
))
&
1
)
==
1
);}},
getLengthInBits
:
function
(){
return
this
.
length
;},
putBit
:
function
(
bit
){
var
bufIndex
=
Math
.
floor
(
this
.
length
/
8
);
if
(
this
.
buffer
.
length
<=
bufIndex
){
this
.
buffer
.
push
(
0
);}
if
(
bit
){
this
.
buffer
[
bufIndex
]
|=
(
0x80
>>>
(
this
.
length
%
8
));}
this
.
length
++
;}};
var
QRCodeLimitLength
=
[[
17
,
14
,
11
,
7
],[
32
,
26
,
20
,
14
],[
53
,
42
,
32
,
24
],[
78
,
62
,
46
,
34
],[
106
,
84
,
60
,
44
],[
134
,
106
,
74
,
58
],[
154
,
122
,
86
,
64
],[
192
,
152
,
108
,
84
],[
230
,
180
,
130
,
98
],[
271
,
213
,
151
,
119
],[
321
,
251
,
177
,
137
],[
367
,
287
,
203
,
155
],[
425
,
331
,
241
,
177
],[
458
,
362
,
258
,
194
],[
520
,
412
,
292
,
220
],[
586
,
450
,
322
,
250
],[
644
,
504
,
364
,
280
],[
718
,
560
,
394
,
310
],[
792
,
624
,
442
,
338
],[
858
,
666
,
482
,
382
],[
929
,
711
,
509
,
403
],[
1003
,
779
,
565
,
439
],[
1091
,
857
,
611
,
461
],[
1171
,
911
,
661
,
511
],[
1273
,
997
,
715
,
535
],[
1367
,
1059
,
751
,
593
],[
1465
,
1125
,
805
,
625
],[
1528
,
1190
,
868
,
658
],[
1628
,
1264
,
908
,
698
],[
1732
,
1370
,
982
,
742
],[
1840
,
1452
,
1030
,
790
],[
1952
,
1538
,
1112
,
842
],[
2068
,
1628
,
1168
,
898
],[
2188
,
1722
,
1228
,
958
],[
2303
,
1809
,
1283
,
983
],[
2431
,
1911
,
1351
,
1051
],[
2563
,
1989
,
1423
,
1093
],[
2699
,
2099
,
1499
,
1139
],[
2809
,
2213
,
1579
,
1219
],[
2953
,
2331
,
1663
,
1273
]];
function
_isSupportCanvas
()
{
return
typeof
CanvasRenderingContext2D
!=
"
undefined
"
;
}
// android 2.x doesn't support Data-URI spec
function
_getAndroid
()
{
var
android
=
false
;
var
sAgent
=
navigator
.
userAgent
;
if
(
/android/i
.
test
(
sAgent
))
{
// android
android
=
true
;
var
aMat
=
sAgent
.
toString
().
match
(
/android
([
0-9
]\.[
0-9
])
/i
);
if
(
aMat
&&
aMat
[
1
])
{
android
=
parseFloat
(
aMat
[
1
]);
}
}
return
android
;
}
var
svgDrawer
=
(
function
()
{
var
Drawing
=
function
(
el
,
htOption
)
{
this
.
_el
=
el
;
this
.
_htOption
=
htOption
;
};
Drawing
.
prototype
.
draw
=
function
(
oQRCode
)
{
var
_htOption
=
this
.
_htOption
;
var
_el
=
this
.
_el
;
var
nCount
=
oQRCode
.
getModuleCount
();
var
nWidth
=
Math
.
floor
(
_htOption
.
width
/
nCount
);
var
nHeight
=
Math
.
floor
(
_htOption
.
height
/
nCount
);
this
.
clear
();
function
makeSVG
(
tag
,
attrs
)
{
var
el
=
document
.
createElementNS
(
'
http://www.w3.org/2000/svg
'
,
tag
);
for
(
var
k
in
attrs
)
if
(
attrs
.
hasOwnProperty
(
k
))
el
.
setAttribute
(
k
,
attrs
[
k
]);
return
el
;
}
var
svg
=
makeSVG
(
"
svg
"
,
{
'
viewBox
'
:
'
0 0
'
+
String
(
nCount
)
+
"
"
+
String
(
nCount
),
'
width
'
:
'
100%
'
,
'
height
'
:
'
100%
'
,
'
fill
'
:
_htOption
.
colorLight
});
svg
.
setAttributeNS
(
"
http://www.w3.org/2000/xmlns/
"
,
"
xmlns:xlink
"
,
"
http://www.w3.org/1999/xlink
"
);
_el
.
appendChild
(
svg
);
svg
.
appendChild
(
makeSVG
(
"
rect
"
,
{
"
fill
"
:
_htOption
.
colorLight
,
"
width
"
:
"
100%
"
,
"
height
"
:
"
100%
"
}));
svg
.
appendChild
(
makeSVG
(
"
rect
"
,
{
"
fill
"
:
_htOption
.
colorDark
,
"
width
"
:
"
1
"
,
"
height
"
:
"
1
"
,
"
id
"
:
"
template
"
}));
for
(
var
row
=
0
;
row
<
nCount
;
row
++
)
{
for
(
var
col
=
0
;
col
<
nCount
;
col
++
)
{
if
(
oQRCode
.
isDark
(
row
,
col
))
{
var
child
=
makeSVG
(
"
use
"
,
{
"
x
"
:
String
(
col
),
"
y
"
:
String
(
row
)});
child
.
setAttributeNS
(
"
http://www.w3.org/1999/xlink
"
,
"
href
"
,
"
#template
"
)
svg
.
appendChild
(
child
);
}
}
}
};
Drawing
.
prototype
.
clear
=
function
()
{
while
(
this
.
_el
.
hasChildNodes
())
this
.
_el
.
removeChild
(
this
.
_el
.
lastChild
);
};
return
Drawing
;
})();
var
useSVG
=
document
.
documentElement
.
tagName
.
toLowerCase
()
===
"
svg
"
;
// Drawing in DOM by using Table tag
var
Drawing
=
useSVG
?
svgDrawer
:
!
_isSupportCanvas
()
?
(
function
()
{
var
Drawing
=
function
(
el
,
htOption
)
{
this
.
_el
=
el
;
this
.
_htOption
=
htOption
;
};
/**
* Draw the QRCode
*
* @param {QRCode} oQRCode
*/
Drawing
.
prototype
.
draw
=
function
(
oQRCode
)
{
var
_htOption
=
this
.
_htOption
;
var
_el
=
this
.
_el
;
var
nCount
=
oQRCode
.
getModuleCount
();
var
nWidth
=
Math
.
floor
(
_htOption
.
width
/
nCount
);
var
nHeight
=
Math
.
floor
(
_htOption
.
height
/
nCount
);
var
aHTML
=
[
'
<table style="border:0;border-collapse:collapse;">
'
];
for
(
var
row
=
0
;
row
<
nCount
;
row
++
)
{
aHTML
.
push
(
'
<tr>
'
);
for
(
var
col
=
0
;
col
<
nCount
;
col
++
)
{
aHTML
.
push
(
'
<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:
'
+
nWidth
+
'
px;height:
'
+
nHeight
+
'
px;background-color:
'
+
(
oQRCode
.
isDark
(
row
,
col
)
?
_htOption
.
colorDark
:
_htOption
.
colorLight
)
+
'
;"></td>
'
);
}
aHTML
.
push
(
'
</tr>
'
);
}
aHTML
.
push
(
'
</table>
'
);
_el
.
innerHTML
=
aHTML
.
join
(
''
);
// Fix the margin values as real size.
var
elTable
=
_el
.
childNodes
[
0
];
var
nLeftMarginTable
=
(
_htOption
.
width
-
elTable
.
offsetWidth
)
/
2
;
var
nTopMarginTable
=
(
_htOption
.
height
-
elTable
.
offsetHeight
)
/
2
;
if
(
nLeftMarginTable
>
0
&&
nTopMarginTable
>
0
)
{
elTable
.
style
.
margin
=
nTopMarginTable
+
"
px
"
+
nLeftMarginTable
+
"
px
"
;
}
};
/**
* Clear the QRCode
*/
Drawing
.
prototype
.
clear
=
function
()
{
this
.
_el
.
innerHTML
=
''
;
};
return
Drawing
;
})()
:
(
function
()
{
// Drawing in Canvas
function
_onMakeImage
()
{
this
.
_elImage
.
src
=
this
.
_elCanvas
.
toDataURL
(
"
image/png
"
);
this
.
_elImage
.
style
.
display
=
"
inline
"
;
this
.
_elCanvas
.
style
.
display
=
"
none
"
;
}
// Android 2.1 bug workaround
// http://code.google.com/p/android/issues/detail?id=5141
if
(
this
.
_android
&&
this
.
_android
<=
2.1
)
{
var
factor
=
1
/
window
.
devicePixelRatio
;
var
drawImage
=
CanvasRenderingContext2D
.
prototype
.
drawImage
;
CanvasRenderingContext2D
.
prototype
.
drawImage
=
function
(
image
,
sx
,
sy
,
sw
,
sh
,
dx
,
dy
,
dw
,
dh
)
{
if
((
"
nodeName
"
in
image
)
&&
/img/i
.
test
(
image
.
nodeName
))
{
for
(
var
i
=
arguments
.
length
-
1
;
i
>=
1
;
i
--
)
{
arguments
[
i
]
=
arguments
[
i
]
*
factor
;
}
}
else
if
(
typeof
dw
==
"
undefined
"
)
{
arguments
[
1
]
*=
factor
;
arguments
[
2
]
*=
factor
;
arguments
[
3
]
*=
factor
;
arguments
[
4
]
*=
factor
;
}
drawImage
.
apply
(
this
,
arguments
);
};
}
/**
* Check whether the user's browser supports Data URI or not
*
* @private
* @param {Function} fSuccess Occurs if it supports Data URI
* @param {Function} fFail Occurs if it doesn't support Data URI
*/
function
_safeSetDataURI
(
fSuccess
,
fFail
)
{
var
self
=
this
;
self
.
_fFail
=
fFail
;
self
.
_fSuccess
=
fSuccess
;
// Check it just once
if
(
self
.
_bSupportDataURI
===
null
)
{
var
el
=
document
.
createElement
(
"
img
"
);
var
fOnError
=
function
()
{
self
.
_bSupportDataURI
=
false
;
if
(
self
.
_fFail
)
{
self
.
_fFail
.
call
(
self
);
}
};
var
fOnSuccess
=
function
()
{
self
.
_bSupportDataURI
=
true
;
if
(
self
.
_fSuccess
)
{
self
.
_fSuccess
.
call
(
self
);
}
};
el
.
onabort
=
fOnError
;
el
.
onerror
=
fOnError
;
el
.
onload
=
fOnSuccess
;
el
.
src
=
"
data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
"
;
// the Image contains 1px data.
return
;
}
else
if
(
self
.
_bSupportDataURI
===
true
&&
self
.
_fSuccess
)
{
self
.
_fSuccess
.
call
(
self
);
}
else
if
(
self
.
_bSupportDataURI
===
false
&&
self
.
_fFail
)
{
self
.
_fFail
.
call
(
self
);
}
};
/**
* Drawing QRCode by using canvas
*
* @constructor
* @param {HTMLElement} el
* @param {Object} htOption QRCode Options
*/
var
Drawing
=
function
(
el
,
htOption
)
{
this
.
_bIsPainted
=
false
;
this
.
_android
=
_getAndroid
();
this
.
_htOption
=
htOption
;
this
.
_elCanvas
=
document
.
createElement
(
"
canvas
"
);
this
.
_elCanvas
.
width
=
htOption
.
width
;
this
.
_elCanvas
.
height
=
htOption
.
height
;
el
.
appendChild
(
this
.
_elCanvas
);
this
.
_el
=
el
;
this
.
_oContext
=
this
.
_elCanvas
.
getContext
(
"
2d
"
);
this
.
_bIsPainted
=
false
;
this
.
_elImage
=
document
.
createElement
(
"
img
"
);
this
.
_elImage
.
alt
=
"
Scan me!
"
;
this
.
_elImage
.
style
.
display
=
"
none
"
;
this
.
_el
.
appendChild
(
this
.
_elImage
);
this
.
_bSupportDataURI
=
null
;
};
/**
* Draw the QRCode
*
* @param {QRCode} oQRCode
*/
Drawing
.
prototype
.
draw
=
function
(
oQRCode
)
{
var
_elImage
=
this
.
_elImage
;
var
_oContext
=
this
.
_oContext
;
var
_htOption
=
this
.
_htOption
;
var
nCount
=
oQRCode
.
getModuleCount
();
var
nWidth
=
_htOption
.
width
/
nCount
;
var
nHeight
=
_htOption
.
height
/
nCount
;
var
nRoundedWidth
=
Math
.
round
(
nWidth
);
var
nRoundedHeight
=
Math
.
round
(
nHeight
);
_elImage
.
style
.
display
=
"
none
"
;
this
.
clear
();
for
(
var
row
=
0
;
row
<
nCount
;
row
++
)
{
for
(
var
col
=
0
;
col
<
nCount
;
col
++
)
{
var
bIsDark
=
oQRCode
.
isDark
(
row
,
col
);
var
nLeft
=
col
*
nWidth
;
var
nTop
=
row
*
nHeight
;
_oContext
.
strokeStyle
=
bIsDark
?
_htOption
.
colorDark
:
_htOption
.
colorLight
;
_oContext
.
lineWidth
=
1
;
_oContext
.
fillStyle
=
bIsDark
?
_htOption
.
colorDark
:
_htOption
.
colorLight
;
_oContext
.
fillRect
(
nLeft
,
nTop
,
nWidth
,
nHeight
);
// 안티 앨리어싱 방지 처리
_oContext
.
strokeRect
(
Math
.
floor
(
nLeft
)
+
0.5
,
Math
.
floor
(
nTop
)
+
0.5
,
nRoundedWidth
,
nRoundedHeight
);
_oContext
.
strokeRect
(
Math
.
ceil
(
nLeft
)
-
0.5
,
Math
.
ceil
(
nTop
)
-
0.5
,
nRoundedWidth
,
nRoundedHeight
);
}
}
this
.
_bIsPainted
=
true
;
};
/**
* Make the image from Canvas if the browser supports Data URI.
*/
Drawing
.
prototype
.
makeImage
=
function
()
{
if
(
this
.
_bIsPainted
)
{
_safeSetDataURI
.
call
(
this
,
_onMakeImage
);
}
};
/**
* Return whether the QRCode is painted or not
*
* @return {Boolean}
*/
Drawing
.
prototype
.
isPainted
=
function
()
{
return
this
.
_bIsPainted
;
};
/**
* Clear the QRCode
*/
Drawing
.
prototype
.
clear
=
function
()
{
this
.
_oContext
.
clearRect
(
0
,
0
,
this
.
_elCanvas
.
width
,
this
.
_elCanvas
.
height
);
this
.
_bIsPainted
=
false
;
};
/**
* @private
* @param {Number} nNumber
*/
Drawing
.
prototype
.
round
=
function
(
nNumber
)
{
if
(
!
nNumber
)
{
return
nNumber
;
}
return
Math
.
floor
(
nNumber
*
1000
)
/
1000
;
};
return
Drawing
;
})();
/**
* Get the type by string length
*
* @private
* @param {String} sText
* @param {Number} nCorrectLevel
* @return {Number} type
*/
function
_getTypeNumber
(
sText
,
nCorrectLevel
)
{
var
nType
=
1
;
var
length
=
_getUTF8Length
(
sText
);
for
(
var
i
=
0
,
len
=
QRCodeLimitLength
.
length
;
i
<=
len
;
i
++
)
{
var
nLimit
=
0
;
switch
(
nCorrectLevel
)
{
case
QRErrorCorrectLevel
.
L
:
nLimit
=
QRCodeLimitLength
[
i
][
0
];
break
;
case
QRErrorCorrectLevel
.
M
:
nLimit
=
QRCodeLimitLength
[
i
][
1
];
break
;
case
QRErrorCorrectLevel
.
Q
:
nLimit
=
QRCodeLimitLength
[
i
][
2
];
break
;
case
QRErrorCorrectLevel
.
H
:
nLimit
=
QRCodeLimitLength
[
i
][
3
];
break
;
}
if
(
length
<=
nLimit
)
{
break
;
}
else
{
nType
++
;
}
}
if
(
nType
>
QRCodeLimitLength
.
length
)
{
throw
new
Error
(
"
Too long data
"
);
}
return
nType
;
}
function
_getUTF8Length
(
sText
)
{
var
replacedText
=
encodeURI
(
sText
).
toString
().
replace
(
/
\%[
0-9a-fA-F
]{2}
/g
,
'
a
'
);
return
replacedText
.
length
+
(
replacedText
.
length
!=
sText
?
3
:
0
);
}
/**
* @class QRCode
* @constructor
* @example
* new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
*
* @example
* var oQRCode = new QRCode("test", {
* text : "http://naver.com",
* width : 128,
* height : 128
* });
*
* oQRCode.clear(); // Clear the QRCode.
* oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
*
* @param {HTMLElement|String} el target element or 'id' attribute of element.
* @param {Object|String} vOption
* @param {String} vOption.text QRCode link data
* @param {Number} [vOption.width=256]
* @param {Number} [vOption.height=256]
* @param {String} [vOption.colorDark="#000000"]
* @param {String} [vOption.colorLight="#ffffff"]
* @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H]
*/
QRCode
=
function
(
el
,
vOption
)
{
this
.
_htOption
=
{
width
:
256
,
height
:
256
,
typeNumber
:
4
,
colorDark
:
"
#000000
"
,
colorLight
:
"
#ffffff
"
,
correctLevel
:
QRErrorCorrectLevel
.
H
};
if
(
typeof
vOption
===
'
string
'
)
{
vOption
=
{
text
:
vOption
};
}
// Overwrites options
if
(
vOption
)
{
for
(
var
i
in
vOption
)
{
this
.
_htOption
[
i
]
=
vOption
[
i
];
}
}
if
(
typeof
el
==
"
string
"
)
{
el
=
document
.
getElementById
(
el
);
}
if
(
this
.
_htOption
.
useSVG
)
{
Drawing
=
svgDrawer
;
}
this
.
_android
=
_getAndroid
();
this
.
_el
=
el
;
this
.
_oQRCode
=
null
;
this
.
_oDrawing
=
new
Drawing
(
this
.
_el
,
this
.
_htOption
);
if
(
this
.
_htOption
.
text
)
{
this
.
makeCode
(
this
.
_htOption
.
text
);
}
};
/**
* Make the QRCode
*
* @param {String} sText link data
*/
QRCode
.
prototype
.
makeCode
=
function
(
sText
)
{
this
.
_oQRCode
=
new
QRCodeModel
(
_getTypeNumber
(
sText
,
this
.
_htOption
.
correctLevel
),
this
.
_htOption
.
correctLevel
);
this
.
_oQRCode
.
addData
(
sText
);
this
.
_oQRCode
.
make
();
this
.
_el
.
title
=
""
;
this
.
_oDrawing
.
draw
(
this
.
_oQRCode
);
this
.
makeImage
();
};
/**
* Make the Image from Canvas element
* - It occurs automatically
* - Android below 3 doesn't support Data-URI spec.
*
* @private
*/
QRCode
.
prototype
.
makeImage
=
function
()
{
if
(
typeof
this
.
_oDrawing
.
makeImage
==
"
function
"
&&
(
!
this
.
_android
||
this
.
_android
>=
3
))
{
this
.
_oDrawing
.
makeImage
();
}
};
/**
* Clear the QRCode
*/
QRCode
.
prototype
.
clear
=
function
()
{
this
.
_oDrawing
.
clear
();
};
/**
* @name QRCode.CorrectLevel
*/
QRCode
.
CorrectLevel
=
QRErrorCorrectLevel
;
})();
maxkey-web-frontend/maxkey-web-app/src/environments/environment.ts
浏览文件 @
fe82cb8c
...
...
@@ -27,7 +27,7 @@ export const environment = {
production
:
false
,
useHash
:
true
,
api
:
{
baseUrl
:
'
http://sso.maxkey.top:9527
/sign/
'
,
baseUrl
:
'
/sign/
'
,
refreshTokenEnabled
:
true
,
refreshTokenType
:
'
re-request
'
},
...
...
maxkey-web-frontend/maxkey-web-app/src/index.html
浏览文件 @
fe82cb8c
...
...
@@ -27,6 +27,7 @@
<meta
http-equiv=
"description"
content=
"MaxKey Single Sign-On"
>
<link
rel=
"icon"
type=
"image/x-icon"
href=
"favicon.ico"
>
<script
src=
"./assets/transform.js"
></script>
<script
src=
"./assets/qrcode/qrcode.min.js"
></script>
<!-- Apple Touch Icon -->
<!-- <link rel="apple-touch-icon" href="custom-icon.png"> -->
<style
type=
"text/css"
>
...
...
@@ -142,9 +143,9 @@
</div>
</body>
<!--attention http or https-->
<!
--企业微信
--企业微信
<script
src=
"http://wwcdn.weixin.qq.com/node/wework/wwopen/js/wwLogin-1.2.7.js"
></script>
-->
<!--钉钉-->
<!---->
<script
src=
"http://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"
></script>
...
...
@@ -191,4 +192,4 @@
</script>
-->
</html>
\ No newline at end of file
</html>
maxkey-webs/maxkey-web-maxkey/build.gradle
浏览文件 @
fe82cb8c
buildscript
{
repositories
{
maven
{
url
'https://maven.aliyun.com/nexus/content/groups/public/'
}
}
dependencies
{
//springboot jar
classpath
(
"org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
)
}
}
plugins
{
id
'java'
id
"io.spring.dependency-management"
version
"1.0.11.RELEASE"
id
'org.springframework.boot'
version
"${springBootVersion}"
}
apply
plugin:
'io.spring.dependency-management'
description
=
"maxkey-web-maxkey"
//add support for Java
apply
plugin:
'java'
bootJar
{
dependsOn
jar
baseName
=
'maxkey-boot'
version
=
"${project.version}-ga"
mainClass
=
'org.maxkey.MaxKeyApplication'
manifest
{
attributes
(
"Implementation-Title"
:
project
.
name
,
"Implementation-Vendor"
:
project
.
vendor
,
"Created-By"
:
project
.
author
,
"Implementation-Date"
:
java
.
time
.
ZonedDateTime
.
now
(),
"Implementation-Version"
:
project
.
version
)
}
}
dependencies
{
implementation
project
(
":maxkey-common"
)
...
...
@@ -12,8 +43,8 @@ dependencies {
implementation
project
(
":maxkey-authentications:maxkey-authentication-social"
)
implementation
project
(
":maxkey-authentications:maxkey-authentication-captcha"
)
implementation
project
(
":maxkey-authentications:maxkey-authentication-otp"
)
implementation
project
(
":maxkey-authentications:maxkey-authentication-provider"
)
implementation
project
(
":maxkey-authentications:maxkey-authentication-sms"
)
implementation
project
(
":maxkey-authentications:maxkey-authentication-provider"
)
implementation
project
(
":maxkey-authentications:maxkey-authentication-sms"
)
implementation
project
(
":maxkey-protocols:maxkey-protocol-authorize"
)
implementation
project
(
":maxkey-protocols:maxkey-protocol-cas"
)
...
...
@@ -23,5 +54,4 @@ dependencies {
implementation
project
(
":maxkey-protocols:maxkey-protocol-oauth-2.0"
)
implementation
project
(
":maxkey-protocols:maxkey-protocol-saml-2.0"
)
implementation
project
(
":maxkey-protocols:maxkey-protocol-jwt"
)
}
}
\ No newline at end of file
maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/contorller/LoginEntryPoint.java
浏览文件 @
fe82cb8c
...
...
@@ -34,12 +34,11 @@ import org.maxkey.authn.support.rememberme.AbstractRemeberMeManager;
import
org.maxkey.authn.support.rememberme.RemeberMe
;
import
org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService
;
import
org.maxkey.configuration.ApplicationConfig
;
import
org.maxkey.entity.Institutions
;
import
org.maxkey.entity.Message
;
import
org.maxkey.entity.UserInfo
;
import
org.maxkey.constants.ConstsLoginType
;
import
org.maxkey.entity.*
;
import
org.maxkey.password.onetimepwd.AbstractOtpAuthn
;
import
org.maxkey.password.onetimepwd.MailOtpAuthnService
;
import
org.maxkey.password.sms.SmsOtpAuthnService
;
import
org.maxkey.persistence.service.SocialsAssociatesService
;
import
org.maxkey.persistence.service.UserInfoService
;
import
org.maxkey.web.WebConstants
;
import
org.maxkey.web.WebContext
;
...
...
@@ -81,6 +80,9 @@ public class LoginEntryPoint {
@Autowired
SocialSignOnProviderService
socialSignOnProviderService
;
@Autowired
SocialsAssociatesService
socialsAssociatesService
;
@Autowired
KerberosService
kerberosService
;
...
...
@@ -165,6 +167,47 @@ public class LoginEntryPoint {
return
new
Message
<
AuthJwt
>(
Message
.
FAIL
).
buildResponse
();
}
@RequestMapping
(
value
={
"/signin/bindusersocials"
},
produces
=
{
MediaType
.
APPLICATION_JSON_VALUE
})
public
ResponseEntity
<?>
bindusersocials
(
@RequestBody
LoginCredential
credential
)
{
//短信验证码
String
code
=
credential
.
getCode
();
//映射社交服务的账号
String
username
=
credential
.
getUsername
();
//maxkey存储的手机号
String
mobile
=
credential
.
getMobile
();
//社交服务类型
String
authType
=
credential
.
getAuthType
();
UserInfo
userInfo
=
userInfoService
.
findByEmailMobile
(
mobile
);
//验证码验证是否合法
if
(
smsAuthnService
.
getByInstId
(
WebContext
.
getInst
().
getId
()).
validate
(
userInfo
,
code
))
{
//合法进行用户绑定
SocialsAssociate
socialsAssociate
=
new
SocialsAssociate
();
socialsAssociate
.
setUserId
(
userInfo
.
getId
());
socialsAssociate
.
setUsername
(
userInfo
.
getUsername
());
socialsAssociate
.
setProvider
(
authType
);
socialsAssociate
.
setSocialUserId
(
username
);
socialsAssociate
.
setInstId
(
userInfo
.
getInstId
());
//插入Maxkey和社交服务的用户映射表
socialsAssociatesService
.
insert
(
socialsAssociate
);
//设置完成后,进行登录认证
LoginCredential
loginCredential
=
new
LoginCredential
(
socialsAssociate
.
getUsername
(),
""
,
ConstsLoginType
.
SOCIALSIGNON
);
SocialsProvider
socialSignOnProvider
=
socialSignOnProviderService
.
get
(
socialsAssociate
.
getInstId
(),
socialsAssociate
.
getProvider
());
loginCredential
.
setProvider
(
socialSignOnProvider
.
getProviderName
());
Authentication
authentication
=
authenticationProvider
.
authenticate
(
loginCredential
,
true
);
return
new
Message
<
AuthJwt
>(
authTokenService
.
genAuthJwt
(
authentication
)).
buildResponse
();
}
return
new
Message
<
AuthJwt
>(
Message
.
FAIL
).
buildResponse
();
}
/**
* normal
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录