Compare commits

..

39 Commits

Author SHA1 Message Date
7470f8e001 [이민권] 임시 로그 삽입 2023-08-22 18:27:04 +09:00
fc70a9482c [이민권] getProviderInfo 실패시 리턴하지 않는 부분 수정 2023-08-22 18:22:31 +09:00
9ccd97564a [이민권] Unlink 수정 2023-08-22 15:38:51 +09:00
4958cb0b93 [이민권] linkinfo 로그 수정 2023-08-21 19:18:27 +09:00
9c14480be7 [이민권] 게스트 상태에서 링크하는 경우 수정 2023-08-18 17:06:21 +09:00
daf3e3f027 version split 디폴트 이름 변경 2023-08-18 13:56:51 +09:00
2de82b9d2a [이민권] 계정 정보 받아오는 함수 수정 2023-08-17 19:13:01 +09:00
00c2d6e205 [이민권] 언더바 빼먹은거 수정 2023-08-17 18:31:41 +09:00
87d922c558 [이민권] 크래쉬 수정 2023-08-17 18:21:01 +09:00
0be7adefe3 [이민권] api 수정
- unlink시 link collection에 doc 남겨지는 이슈 수정
- linkinfo api가 단순 link 갯수가 아니라 어떤 platform에 연동 하였는지 반환하도록 수정
- 계정 삭제 api인 delacc api 추가
2023-08-17 14:23:00 +09:00
3a9f81f1cb divisionsSerialized가 잘못 덮어씌어진 문제 수정 2023-08-17 12:36:04 +09:00
a97b9f0983 Merge branch 'master' into kd-live 2023-08-16 21:44:47 +09:00
9edea29983 Merge branch 'master' into kd-live 2023-08-09 17:39:30 +09:00
8e908982a8 Merge branch 'master' into kd-live 2023-08-09 17:24:40 +09:00
6b68d918ba 모듈 업데이트 2023-08-01 14:18:38 +09:00
3216e2620a Merge branch 'master' into kd-live 2023-07-10 18:12:57 +09:00
f66904d428 Merge branch 'master' into kd-live 2023-07-07 15:33:18 +09:00
8d70777269 안쓰는 로그 제거 2023-06-30 18:04:25 +09:00
15ead6b0bc Merge branch 'master' into kd-live 2023-06-30 18:01:43 +09:00
97636ce31d Merge branch 'master' into kd-live 2023-06-29 21:32:19 +09:00
2b4becdb61 Merge branch 'master' into kd-live 2023-06-29 21:22:19 +09:00
429bbd1e7a Merge branch 'master' into kd-live 2023-06-29 16:09:40 +09:00
1c397da77a Merge branch 'master' into kd-live 2023-06-28 16:45:34 +09:00
5502c4d744 Merge commit 'cb08ecb53a4d472919f24baaf4e8069412c2870c' into kd-live 2023-06-28 16:18:48 +09:00
cb793092e9 Merge branch 'master' into kd-live 2023-06-28 15:28:11 +09:00
13f6492e5f Merge branch 'master' into kd-live 2023-06-28 15:17:21 +09:00
f739eb3a8b Merge branch 'master' into kd-live 2023-06-27 19:13:19 +09:00
c95d7747cd Merge branch 'master' into kd-live 2023-06-27 19:04:01 +09:00
841dad4992 Merge branch 'master' into kd-live 2023-06-27 18:51:12 +09:00
ff7d56152e Merge branch 'master' into kd-live 2023-06-26 17:34:42 +09:00
2acca6dbe8 Merge branch 'master' into kd-live 2023-06-23 17:58:56 +09:00
484db90037 로그 추가 2023-06-23 17:35:25 +09:00
b06eb86578 되돌림을 되돌림 2023-06-23 17:21:36 +09:00
9704decb7a 되돌림 2023-06-23 17:05:19 +09:00
767d6bf002 Merge branch 'master' into kd-live 2023-06-23 16:53:16 +09:00
1f7421dd2e Merge branch 'master' into kd-live 2023-06-23 16:43:32 +09:00
53701d61f8 Merge branch 'master' into kd-live 2023-06-23 16:27:35 +09:00
6d02eb092c 로그 추가 2023-06-23 16:27:31 +09:00
7bee78a875 live용 설정 추가 2023-06-22 20:20:50 +09:00
29 changed files with 993 additions and 10155 deletions

View File

@ -1,37 +0,0 @@
// Import the functions you need from the SDKs you need
import { initializeApp } from './firebase-app.js';
import { getAnalytics, logEvent } from './firebase-analytics.js';
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "{{.FBA_apiKey}}",
authDomain: "{{.FBA_authDomain}}",
databaseURL: "{{.FBA_databaseURL}}",
projectId: "{{.FBA_projectId}}",
storageBucket: "{{.FBA_storageBucket}}",
messagingSenderId: "{{.FBA_messagingSenderId}}",
appId: "{{.FBA_appId}}",
measurementId: "{{.FBA_measurementId}}"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
// LogEvent('DESKTOP_TEST8');
export function LogEvent(args){
if ( arguments.length == 1) {
logEvent(analytics, arguments[0]);
} else {
logEvent(analytics, arguments[0], arguments[1]);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,5 @@
{ {
"maingate_mongodb_url": "mongodb://...", "maingate_mongodb_url": "mongodb://...",
"session_storage": "",
"session_ttl" : 3600,
"autologin_ttl": 604800, "autologin_ttl": 604800,
"maximum_num_link_account": 10, "maximum_num_link_account": 10,
"redirect_base_url": "", "redirect_base_url": "",
@ -28,15 +25,6 @@
"firebase_admin_sdk_credentialfile": "", "firebase_admin_sdk_credentialfile": "",
"firebase_google_analytics_jssdk_apikey": "",
"firebase_google_analytics_jssdk_authdomain": "",
"firebase_google_analytics_jssdk_databaseurl": "",
"firebase_google_analytics_jssdk_projectid": "",
"firebase_google_analytics_jssdk_storagebucket": "",
"firebase_google_analytics_jssdk_messagingsenderid": "",
"firebase_google_analytics_jssdk_apiid": "",
"firebase_google_analytics_jssdk_measurementid": "",
"maingate_global_admins" : [ "maingate_global_admins" : [
"mountain@action2quare.com" "mountain@action2quare.com"
] ]

View File

@ -2,7 +2,9 @@ package core
import ( import (
"bytes" "bytes"
"crypto/md5"
"encoding/binary" "encoding/binary"
"encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -25,6 +27,7 @@ import (
) )
type FileDocumentDesc struct { type FileDocumentDesc struct {
Service string `bson:"service" json:"service"`
Key string `bson:"key" json:"key"` Key string `bson:"key" json:"key"`
Src string `bson:"src" json:"src"` Src string `bson:"src" json:"src"`
Link string `bson:"link" json:"link"` Link string `bson:"link" json:"link"`
@ -107,6 +110,11 @@ var seq = uint32(0)
func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error { func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error {
if r.Method == "PUT" { if r.Method == "PUT" {
servicename := r.FormValue("service")
hasher := md5.New()
hasher.Write([]byte(servicename))
subfolder := hex.EncodeToString(hasher.Sum(nil))[:8]
infile, header, err := r.FormFile("file") infile, header, err := r.FormFile("file")
if err != nil { if err != nil {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
@ -122,16 +130,17 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
var b [5]byte var b [5]byte
binary.BigEndian.PutUint32(b[0:4], uint32(time.Now().Unix())) binary.BigEndian.PutUint32(b[0:4], uint32(time.Now().Unix()))
b[4] = byte(atomic.AddUint32(&seq, 1) % 255) b[4] = byte(atomic.AddUint32(&seq, 1) % 255)
rf := hex.EncodeToString(b[1:])
newidstr := subfolder + rf
newidbt, _ := hex.DecodeString(newidstr)
newidobj := primitive.NewObjectID() newidobj := primitive.NewObjectID()
copy(newidobj[:], b[1:]) copy(newidobj[:], newidbt[:8])
rf := newidobj.Hex()
var link string var link string
if extract { if extract {
link = path.Join("static", rf) link = path.Join("static", subfolder, rf)
} else { } else {
link = path.Join("static", rf, header.Filename) link = path.Join("static", subfolder, rf, header.Filename)
} }
newdoc := FileDocumentDesc{ newdoc := FileDocumentDesc{
@ -142,9 +151,11 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
Link: link, Link: link,
Desc: desc, Desc: desc,
Key: rf, Key: rf,
Service: servicename,
} }
_, _, err = caller.mg.mongoClient.UpsertOne(CollectionFile, bson.M{ _, _, err = caller.mg.mongoClient.UpsertOne(CollectionFile, bson.M{
"_id": newidobj, "_id": newidobj,
"service": servicename,
"key": rf, "key": rf,
}, newdoc) }, newdoc)
@ -158,83 +169,47 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
return nil return nil
} }
func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error {
mg := caller.mg
logger.Println("blockAPI :", r.Method)
switch r.Method {
case "GET":
target, ok := gocommon.ReadObjectIDFormValue(r.Form, "accid")
if !ok {
// 페이지네이션 해야할 듯
//json.NewEncoder(w).Encode(mg.bl.all())
} else if !target.IsZero() {
var blocked []blockinfo
if err := caller.mg.mongoClient.FindAllAs(CollectionBlock, bson.M{
"accid": target,
}, &blocked); err == nil {
json.NewEncoder(w).Encode(blocked)
}
}
case "PUT":
var targets struct {
Start primitive.DateTime
End primitive.DateTime
Accounts map[primitive.ObjectID]primitive.M // accid->meta
}
if err := gocommon.MakeDecoder(r).Decode(&targets); err != nil {
return err
}
for accid, meta := range targets.Accounts {
bi := blockinfo{
Start: targets.Start,
End: targets.End,
Meta: meta,
}
_, err := mg.mongoClient.Collection(CollectionBlock).InsertOne(r.Context(), bi)
if err != nil {
logger.Println("account is not blocked. err :", err)
} else {
logger.Println("account is blocked :", meta)
mg.sessionProvider.RevokeAll(accid)
}
}
case "DELETE":
id := r.URL.Query().Get("id")
if len(id) == 0 {
return errors.New("id param is missing")
}
idobj, err := primitive.ObjectIDFromHex(id)
if err != nil {
return err
}
mg.mongoClient.Delete(CollectionBlock, bson.M{"_id": idobj})
}
return nil
}
func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) error { func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) error {
mg := caller.mg mg := caller.mg
switch r.Method { if r.Method == "GET" {
case "GET": // if !caller.isAdminOrValidToken() {
var all []whitelistmember // logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
if err := mg.mongoClient.AllAs(CollectionWhitelist, &all); err == nil { // w.WriteHeader(http.StatusUnauthorized)
enc := json.NewEncoder(w) // return nil
enc.Encode(all) // }
all, err := mg.mongoClient.All(CollectionWhitelist)
if err != nil {
return err
} }
case "PUT":
if len(all) > 0 {
var notexp []primitive.M
for _, v := range all {
if _, exp := v["_ts"]; !exp {
notexp = append(notexp, v)
}
}
allraw, _ := json.Marshal(notexp)
w.Write(allraw)
}
} else if r.Method == "PUT" {
body, _ := io.ReadAll(r.Body) body, _ := io.ReadAll(r.Body)
var member whitelistmember var member whitelistmember
if err := json.Unmarshal(body, &member); err != nil { if err := json.Unmarshal(body, &member); err != nil {
return err return err
} }
member.ExpiredAt = 0
member.Id = primitive.NewObjectID() // if !caller.isAdminOrValidToken() {
// logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
// w.WriteHeader(http.StatusUnauthorized)
// return nil
// }
member.Expired = 0
_, _, err := mg.mongoClient.Update(CollectionWhitelist, bson.M{ _, _, err := mg.mongoClient.Update(CollectionWhitelist, bson.M{
"_id": member.Id, "_id": primitive.NewObjectID(),
}, bson.M{ }, bson.M{
"$set": &member, "$set": &member,
}, options.Update().SetUpsert(true)) }, options.Update().SetUpsert(true))
@ -242,7 +217,7 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
if err != nil { if err != nil {
return err return err
} }
case "DELETE": } else if r.Method == "DELETE" {
id := r.URL.Query().Get("id") id := r.URL.Query().Get("id")
if len(id) == 0 { if len(id) == 0 {
@ -274,7 +249,9 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
if mg.service().Id.IsZero() { if mg.service().Id.IsZero() {
logger.Println(" id is zero") logger.Println(" id is zero")
newService := serviceDescription{ newService := serviceDescription{
ServiceDescriptionSummary: ServiceDescriptionSummary{
Id: primitive.NewObjectID(), Id: primitive.NewObjectID(),
},
} }
if err := newService.prepare(caller.mg); err != nil { if err := newService.prepare(caller.mg); err != nil {
logger.Println(" prepare failed :", err) logger.Println(" prepare failed :", err)
@ -283,7 +260,7 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(&newService)) atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(&newService))
} }
w.Write(mg.service().serviceSerialized) w.Write(mg.service().divisionsSerialized)
} else if r.Method == "POST" { } else if r.Method == "POST" {
body, _ := io.ReadAll(r.Body) body, _ := io.ReadAll(r.Body)
var service serviceDescription var service serviceDescription
@ -342,109 +319,6 @@ func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) e
return nil return nil
} }
func (caller apiCaller) couponAPI(w http.ResponseWriter, r *http.Request) error {
switch r.Method {
case "PUT":
// 쿠폰 생성
logger.Println("begin generateCoupons")
generateCoupons(caller.mg.mongoClient, w, r)
case "POST":
// TODO : 쿠폰 사용
// 쿠폰 사용 표시 해주고 내용을 응답
logger.Println("begin useCoupon")
useCoupon(caller.mg.mongoClient, w, r)
case "GET":
// 쿠폰 조회
if r.Form.Has("code") {
// 쿠폰 코드 조회
logger.Println("begin queryCoupon")
queryCoupon(caller.mg.mongoClient, w, r)
} else if r.Form.Has("name") {
// 쿠폰 코드 다운
logger.Println("begin downloadCoupons")
downloadCoupons(caller.mg.mongoClient, w, r)
} else {
// 쿠폰 이름 목록
logger.Println("begin listAllCouponNames")
listAllCouponNames(caller.mg.mongoClient, w, r)
}
}
return nil
}
type accountlinkinfo struct {
Uid string `json:"uid"`
Platform string `json:"platform"`
}
func (caller apiCaller) userinfoAPI(w http.ResponseWriter, r *http.Request) error {
mg := caller.mg
if r.Method == "GET" {
// 계정 조회
accid, _ := gocommon.ReadObjectIDFormValue(r.Form, "accid")
if len(accid) > 0 {
all, err := mg.mongoClient.FindAll(CollectionAccount, bson.M{
"accid": accid,
}, options.Find().SetProjection(bson.M{"_id": 1, "accid": 1}))
if err != nil {
return err
}
var linkinfos []accountlinkinfo
for _, doc := range all {
id := doc["_id"].(primitive.ObjectID)
link, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
"_id": id,
}, options.FindOne().SetProjection(bson.M{"_id": 1, "platform": 1, "uid": 1}))
if err != nil {
logger.Error("link failed. FindOneAndUpdate link err:", err)
w.WriteHeader(http.StatusInternalServerError)
return err
}
var info accountlinkinfo
info.Platform = link["platform"].(string)
info.Uid = link["uid"].(string)
linkinfos = append(linkinfos, info)
}
enc := json.NewEncoder(w)
enc.Encode(linkinfos)
}
} else if r.Method == "POST" {
r.ParseMultipartForm(32 << 20)
var body struct {
Platform string
Uid []string
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
return err
}
if len(body.Platform) > 0 && len(body.Uid) > 0 {
output := make(map[string]any)
for _, uid := range body.Uid {
link, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
"platform": body.Platform,
"uid": uid,
}, options.FindOne().SetProjection(bson.M{"_id": 1}))
if err != nil {
return err
}
output[uid] = link["_id"]
}
json.NewEncoder(w).Encode(output)
}
}
return nil
}
var errApiTokenMissing = errors.New("mg-x-api-token is missing") var errApiTokenMissing = errors.New("mg-x-api-token is missing")
func (caller apiCaller) configAPI(w http.ResponseWriter, r *http.Request) error { func (caller apiCaller) configAPI(w http.ResponseWriter, r *http.Request) error {
@ -485,8 +359,6 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
r.Body.Close() r.Body.Close()
}() }()
r.ParseMultipartForm(32 << 20)
var userinfo map[string]any var userinfo map[string]any
if !*devflag { if !*devflag {
@ -567,12 +439,6 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
err = caller.maintenanceAPI(w, r) err = caller.maintenanceAPI(w, r)
} else if strings.HasSuffix(r.URL.Path, "/files") { } else if strings.HasSuffix(r.URL.Path, "/files") {
err = caller.filesAPI(w, r) err = caller.filesAPI(w, r)
} else if strings.HasSuffix(r.URL.Path, "/block") {
err = caller.blockAPI(w, r)
} else if strings.HasSuffix(r.URL.Path, "/coupon") {
err = caller.couponAPI(w, r)
} else if strings.HasSuffix(r.URL.Path, "/userinfo") {
err = caller.userinfoAPI(w, r)
} }
if err != nil { if err != nil {

View File

@ -1,377 +0,0 @@
package core
import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
"math/rand"
"net/http"
"strings"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
"repositories.action2quare.com/ayo/gocommon"
coupon "repositories.action2quare.com/ayo/gocommon/coupon"
"repositories.action2quare.com/ayo/gocommon/logger"
)
const (
CollectionCoupon = gocommon.CollectionName("coupon")
CollectionCouponUse = gocommon.CollectionName("coupon_use")
)
type couponDoc struct {
Name string `json:"name" bson:"name"`
Effect string `json:"effect" bson:"effect"`
Desc string `json:"desc" bson:"desc"`
Total int64 `json:"total" bson:"total"`
Remains []string `json:"remains,omitempty" bson:"remains,omitempty"`
Used []string `json:"used,omitempty" bson:"used,omitempty"`
}
func makeCouponKey(roundnum uint32, uid []byte) string {
left := binary.BigEndian.Uint16(uid[0:2])
right := binary.BigEndian.Uint16(uid[2:4])
multi := uint32(left) * uint32(right)
xor := roundnum ^ multi
final := make([]byte, 8)
binary.LittleEndian.PutUint32(final, xor)
copy(final[4:], uid)
return fmt.Sprintf("%s-%s-%s-%s", hex.EncodeToString(final[0:2]), hex.EncodeToString(final[2:4]), hex.EncodeToString(final[4:6]), hex.EncodeToString(final[6:8]))
}
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
func makeCouponCodes(name string, count int) (string, map[string]string) {
checkunique := make(map[string]bool)
keys := make(map[string]string)
uid := make([]byte, 4)
roundHash, roundnum := coupon.MakeCouponRoundHash(name)
for len(keys) < count {
r.Read(uid)
code := makeCouponKey(roundnum, uid)
if _, ok := checkunique[code]; !ok {
checkunique[code] = true
keys[hex.EncodeToString(uid)] = code
}
}
return roundHash, keys
}
func generateCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
name, _ := gocommon.ReadStringFormValue(r.Form, "name")
effect, _ := gocommon.ReadStringFormValue(r.Form, "effect")
count, _ := gocommon.ReadIntegerFormValue(r.Form, "count")
desc, _ := gocommon.ReadStringFormValue(r.Form, "desc")
if count == 0 {
logger.Println("[generateCoupons] count == 0")
w.WriteHeader(http.StatusBadRequest)
return
}
roundHash, _ := coupon.MakeCouponRoundHash(name)
roundObj, _ := primitive.ObjectIDFromHex(roundHash + roundHash + roundHash)
if count < 0 {
// 무한 쿠폰이므로 그냥 문서 생성해 주고 끝
if _, _, err := mongoClient.Update(CollectionCoupon, bson.M{
"_id": roundObj,
}, bson.M{
"$set": &couponDoc{
Name: name,
Effect: effect,
Desc: desc,
Total: -1,
},
}, options.Update().SetUpsert(true)); err != nil {
logger.Println("[generateCoupons] Update failed :", err)
w.WriteHeader(http.StatusInternalServerError)
}
return
}
// effect가 비어있으면 기존의 roundName에 갯수를 추가해 준다
// effect가 비어있지 않으면 roundName이 겹쳐서는 안된다.
coupondoc, err := mongoClient.FindOne(CollectionCoupon, bson.M{"_id": roundObj})
if err != nil {
logger.Println("[generateCoupons] FindOne failed :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
lastKeys := make(map[string]bool)
if coupondoc != nil {
if r, ok := coupondoc["remains"]; ok {
remains := r.(primitive.A)
for _, uid := range remains {
lastKeys[uid.(string)] = true
}
}
}
issuedKeys := make(map[string]string)
for len(issuedKeys) < int(count) {
_, vs := makeCouponCodes(name, int(count)-len(issuedKeys))
for k, v := range vs {
if _, ok := lastKeys[k]; !ok {
// 기존 키와 중복되지 않는 것만
issuedKeys[k] = v
}
}
}
var coupons []string
var uids []string
for uid, code := range issuedKeys {
uids = append(uids, uid)
coupons = append(coupons, code)
}
if coupondoc != nil {
_, _, err = mongoClient.Update(CollectionCoupon, bson.M{
"_id": roundObj,
}, bson.M{
"$push": bson.M{"remains": bson.M{"$each": uids}},
"$inc": bson.M{"total": count},
}, options.Update().SetUpsert(true))
} else {
_, _, err = mongoClient.Update(CollectionCoupon, bson.M{
"_id": roundObj,
}, bson.M{
"$push": bson.M{"remains": bson.M{"$each": uids}},
"$set": couponDoc{
Name: name,
Effect: effect,
Desc: desc,
Total: count,
},
}, options.Update().SetUpsert(true))
}
if err != nil {
logger.Println("[generateCoupons] Update failed :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
enc := json.NewEncoder(w)
enc.Encode(coupons)
}
func downloadCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
name, _ := gocommon.ReadStringFormValue(r.Form, "name")
if len(name) == 0 {
logger.Println("[downloadCoupons] name is empty")
w.WriteHeader(http.StatusBadRequest)
return
}
round, _ := coupon.MakeCouponRoundHash(name)
roundObj, err := primitive.ObjectIDFromHex(round + round + round)
if err != nil {
// 유효하지 않은 형식의 code
logger.Println("[downloadCoupons] ObjectIDFromHex failed :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
var coupon couponDoc
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
"_id": roundObj,
}, &coupon, options.FindOne().SetProjection(bson.M{"_id": 0, "remains": 1})); err != nil {
logger.Println("[downloadCoupons] FindOne failed :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
roundnum := binary.BigEndian.Uint32(roundObj[:])
var coupons []string
for _, uid := range coupon.Remains {
decUid, err := hex.DecodeString(uid)
if err != nil {
logger.Println("downloadCoupons Fail", err)
continue
}
coupons = append(coupons, makeCouponKey(roundnum, decUid))
}
enc := json.NewEncoder(w)
enc.Encode(coupons)
}
func queryCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
code, _ := gocommon.ReadStringFormValue(r.Form, "code")
if len(code) == 0 {
logger.Println("[queryCoupon] code is empty")
w.WriteHeader(http.StatusBadRequest)
return
}
round, _ := coupon.DisolveCouponCode(code)
if len(round) == 0 {
// 유효하지 않은 형식의 code
// 쿠폰 이름일 수 있으므로 round hash를 계산한다.
round, _ = coupon.MakeCouponRoundHash(code)
}
roundObj, err := primitive.ObjectIDFromHex(round + round + round)
if err != nil {
// 유효하지 않은 형식의 code
logger.Println("[queryCoupon] ObjectIDFromHex failed :", err)
w.WriteHeader(http.StatusBadRequest)
return
}
var coupon couponDoc
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
"_id": roundObj,
}, &coupon, options.FindOne().SetProjection(bson.M{"effect": 1, "name": 1, "reason": 1, "total": 1, "desc": 1}).SetReturnKey(false)); err != nil {
logger.Println("[queryCoupon] FindOneAs failed :", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
enc := json.NewEncoder(w)
enc.Encode(coupon)
}
func listAllCouponNames(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
all, err := mongoClient.FindAll(CollectionCoupon, bson.M{}, options.Find().SetProjection(bson.M{"name": 1}))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
var names []string
for _, doc := range all {
names = append(names, doc["name"].(string))
}
enc := json.NewEncoder(w)
enc.Encode(names)
}
func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
acc, ok := gocommon.ReadObjectIDFormValue(r.Form, "accid")
if !ok || acc.IsZero() {
w.WriteHeader(http.StatusBadRequest)
return
}
code, _ := gocommon.ReadStringFormValue(r.Form, "code")
code = strings.TrimSpace(code)
if len(code) == 0 {
w.WriteHeader(http.StatusBadRequest)
return
}
round, key := coupon.DisolveCouponCode(code)
if len(round) == 0 {
// couponId가 쿠폰 이름일 수도 있다. 무한 쿠폰
round, _ = coupon.MakeCouponRoundHash(code)
}
// 쿠폰 사용 유무 검사
alreadyused, err := mongoClient.Exists(CollectionCouponUse, bson.M{
"_id": acc,
"rounds": round,
})
if err != nil {
logger.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if alreadyused {
// 이미 이 라운드의 쿠폰을 사용한 적이 있다.
w.WriteHeader(http.StatusConflict)
return
}
var coupon couponDoc
roundObj, _ := primitive.ObjectIDFromHex(round + round + round)
if len(key) == 0 {
// 무한 쿠폰일 수 있으므로 존재하는지 확인
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
"_id": roundObj,
}, &coupon, options.FindOne().SetProjection(bson.M{"_id": 0, "effect": 1, "name": 1, "reason": 1, "total": 1})); err != nil {
logger.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if coupon.Total > 0 {
// 무한 쿠폰 아니네?
w.WriteHeader(http.StatusBadRequest)
return
}
} else {
// 2. 쿠폰을 하나 꺼냄
matched, _, err := mongoClient.Update(CollectionCoupon, bson.M{
"_id": roundObj,
"remains": key,
}, bson.M{
"$pull": bson.M{"remains": key},
})
if err != nil {
logger.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if !matched {
// 쿠폰이 없다.
w.WriteHeader(http.StatusBadRequest)
return
}
// 3. round의 효과 읽기
if err := mongoClient.FindOneAndUpdateAs(CollectionCoupon, bson.M{
"_id": roundObj,
}, bson.M{
"$push": bson.M{"used": key},
}, &coupon, options.FindOneAndUpdate().SetProjection(bson.M{"effect": 1})); err != nil {
logger.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
if len(coupon.Effect) == 0 {
// 쿠폰이 없네?
w.WriteHeader(http.StatusBadRequest)
return
}
// 4. 쿠폰은 사용한 것으로 표시
// 이제 이 아래에서 실패하면 이 쿠폰은 못쓴다.
updated, _, err := mongoClient.Update(CollectionCouponUse, bson.M{
"_id": acc,
}, bson.M{
"$push": bson.M{"rounds": round},
"$set": bson.M{round + ".id": code},
"$currentDate": bson.M{round + ".ts": true},
}, options.Update().SetUpsert(true))
if err != nil {
logger.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if !updated {
logger.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write([]byte(coupon.Effect))
}

View File

@ -1,9 +0,0 @@
package core
import (
"testing"
)
func TestMakeLocalUniqueId(t *testing.T) {
}

View File

@ -9,19 +9,18 @@ import (
"fmt" "fmt"
"io" "io"
"math/big" "math/big"
"math/rand"
"net" "net"
"net/http" "net/http"
"os" "os"
"strings" "strings"
"sync/atomic" "sync/atomic"
"text/template"
"time" "time"
"unsafe" "unsafe"
"repositories.action2quare.com/ayo/gocommon" "repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/flagx" "repositories.action2quare.com/ayo/gocommon/flagx"
"repositories.action2quare.com/ayo/gocommon/logger" "repositories.action2quare.com/ayo/gocommon/logger"
"repositories.action2quare.com/ayo/gocommon/session"
"github.com/golang-jwt/jwt" "github.com/golang-jwt/jwt"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
@ -36,10 +35,10 @@ import (
var devflag = flagx.Bool("dev", false, "") var devflag = flagx.Bool("dev", false, "")
var noauth = flagx.Bool("noauth", false, "") var noauth = flagx.Bool("noauth", false, "")
var authtype = flagx.String("auth", "on", "on|off|both")
var ( var (
CollectionLink = gocommon.CollectionName("link") CollectionLink = gocommon.CollectionName("link")
CollectionAuth = gocommon.CollectionName("auth")
CollectionWhitelist = gocommon.CollectionName("whitelist") CollectionWhitelist = gocommon.CollectionName("whitelist")
CollectionService = gocommon.CollectionName("service") CollectionService = gocommon.CollectionName("service")
CollectionAccount = gocommon.CollectionName("account") CollectionAccount = gocommon.CollectionName("account")
@ -58,7 +57,6 @@ const (
AuthPlatformMicrosoft = "microsoft" AuthPlatformMicrosoft = "microsoft"
AuthPlatformApple = "apple" AuthPlatformApple = "apple"
AuthPlatformTwitter = "twitter" AuthPlatformTwitter = "twitter"
AuthPlatformHybeim = "hybeim"
) )
const ( const (
@ -74,12 +72,56 @@ func SessionTTL() time.Duration {
return sessionTTL return sessionTTL
} }
type mongoAuthCell struct {
src *gocommon.Authinfo
}
func (ac *mongoAuthCell) ToAuthinfo() *gocommon.Authinfo {
if ac.src == nil {
logger.Error("mongoAuthCell ToAuthinfo failed. ac.src is nil")
}
return ac.src
}
func (ac *mongoAuthCell) ToBytes() []byte {
bt, _ := json.Marshal(ac.src)
return bt
}
func makeAuthCollection(mongoClient gocommon.MongoClient, sessionTTL time.Duration) *gocommon.AuthCollection {
authcoll := gocommon.MakeAuthCollection(sessionTTL)
authcoll.SessionRemoved = func(sk string) {
skid, _ := primitive.ObjectIDFromHex(sk)
mongoClient.Delete(CollectionAuth, bson.M{
"sk": skid,
})
}
authcoll.QuerySession = func(sk string, token string) gocommon.AuthinfoCell {
skid, _ := primitive.ObjectIDFromHex(sk)
var outcell mongoAuthCell
err := mongoClient.FindOneAs(CollectionAuth, bson.M{
"sk": skid,
}, &outcell.src, options.FindOne().SetHint("skonly"))
if err != nil {
logger.Error("QuerySession failed :", err)
return nil
}
if outcell.src == nil {
return nil
}
return &outcell
}
return authcoll
}
type maingateConfig struct { type maingateConfig struct {
session.SessionConfig `json:",inline"`
MustUseChecksum bool `json:"maingate_must_checksum"`
Mongo string `json:"maingate_mongodb_url"` Mongo string `json:"maingate_mongodb_url"`
SessionTTL int64 `json:"maingate_session_ttl"`
Autologin_ttl int64 `json:"autologin_ttl"` Autologin_ttl int64 `json:"autologin_ttl"`
AccDelTTL int64 `json:"acc_del_ttl"`
MaximumNumLinkAccount int64 `json:"maximum_num_link_account"` MaximumNumLinkAccount int64 `json:"maximum_num_link_account"`
RedirectBaseUrl string `json:"redirect_base_url"` RedirectBaseUrl string `json:"redirect_base_url"`
GoogleClientId string `json:"google_client_id"` GoogleClientId string `json:"google_client_id"`
@ -100,24 +142,6 @@ type maingateConfig struct {
FirebaseAdminSDKCredentialFile string `json:"firebase_admin_sdk_credentialfile"` FirebaseAdminSDKCredentialFile string `json:"firebase_admin_sdk_credentialfile"`
SteamAppId string `json:"steam_app_id"` SteamAppId string `json:"steam_app_id"`
SteamPublisherAuthKey string `json:"steam_publisher_authkey"` SteamPublisherAuthKey string `json:"steam_publisher_authkey"`
GlobalMaingateToken string `json:"maingate_api_token"`
HybeImProjectIdstring string `json:"hybeim_projectid"`
HybeImServiceIdstring string `json:"hybeim_serviceid"`
HybeImAccessKey string `json:"hybeim_acesskey"`
HybeImEndPoint string `json:"hybeim_Endpoint"`
Firebase_Google_Analytics_JS_SDK_Config
}
type Firebase_Google_Analytics_JS_SDK_Config struct {
FGA_apiKey string `json:"firebase_google_analytics_jssdk_apikey"`
FGA_authDomain string `json:"firebase_google_analytics_jssdk_authdomain"`
FGA_databaseURL string `json:"firebase_google_analytics_jssdk_databaseurl"`
FGA_projectId string `json:"firebase_google_analytics_jssdk_projectid"`
FGA_storageBucket string `json:"firebase_google_analytics_jssdk_storagebucket"`
FGA_messagingSenderId string `json:"firebase_google_analytics_jssdk_messagingsenderid"`
FGA_appId string `json:"firebase_google_analytics_jssdk_apiid"`
FGA_measurementId string `json:"ffirebase_google_analytics_jssdk_measurementid"`
} }
type globalAdmins struct { type globalAdmins struct {
@ -135,32 +159,29 @@ func (ga *globalAdmins) parse() {
ga.modtime = gocommon.ConfigModTime() ga.modtime = gocommon.ConfigModTime()
} }
type firebaseClient struct {
firebaseAppClient *auth.Client
firebaseAppContext context.Context
}
// Maingate : // Maingate :
type Maingate struct { type Maingate struct {
maingateConfig
mongoClient gocommon.MongoClient mongoClient gocommon.MongoClient
sessionProvider session.Provider auths *gocommon.AuthCollection
//services servicelist //services servicelist
serviceptr unsafe.Pointer serviceptr unsafe.Pointer
admins unsafe.Pointer admins unsafe.Pointer
wl whitelist
tokenEndpoints map[string]string tokenEndpoints map[string]string
authorizationEndpoints map[string]string authorizationEndpoints map[string]string
userinfoEndpoint map[string]string userinfoEndpoint map[string]string
jwksUri map[string]string jwksUri map[string]string
firebaseAppClient *auth.Client
firebase *firebaseClient firebaseAppContext context.Context
} }
var config maingateConfig
// New : // New :
func New(ctx context.Context) (*Maingate, error) { func New(ctx context.Context) (*Maingate, error) {
var config maingateConfig
if err := gocommon.LoadConfig(&config); err != nil { if err := gocommon.LoadConfig(&config); err != nil {
return nil, err return nil, err
} }
@ -170,15 +191,12 @@ func New(ctx context.Context) (*Maingate, error) {
admins.parse() admins.parse()
} }
if len(config.SessionStorage) == 0 {
return nil, errors.New("maingate_session_storage is missing")
}
if config.SessionTTL == 0 { if config.SessionTTL == 0 {
config.SessionTTL = 3600 config.SessionTTL = 3600
} }
mg := Maingate{ mg := Maingate{
maingateConfig: config,
admins: unsafe.Pointer(&admins), admins: unsafe.Pointer(&admins),
tokenEndpoints: make(map[string]string), tokenEndpoints: make(map[string]string),
authorizationEndpoints: make(map[string]string), authorizationEndpoints: make(map[string]string),
@ -188,32 +206,22 @@ func New(ctx context.Context) (*Maingate, error) {
err := mg.prepare(ctx) err := mg.prepare(ctx)
if err != nil { if err != nil {
logger.Error("mg.prepare() failed :", err)
return nil, err return nil, err
} }
if len(*authtype) == 0 { if !*noauth {
*authtype = "on" opt := option.WithCredentialsFile(mg.FirebaseAdminSDKCredentialFile)
}
if !*noauth && (*authtype == "on" || *authtype == "both") {
if len(config.FirebaseAdminSDKCredentialFile) > 0 {
opt := option.WithCredentialsFile(config.FirebaseAdminSDKCredentialFile)
firebaseApp, err := firebase.NewApp(context.Background(), nil, opt) firebaseApp, err := firebase.NewApp(context.Background(), nil, opt)
if err != nil { if err != nil {
logger.Error("firebase admin error initializing app failed :", err) logger.Error("firebase admin error initializing app failed :", err)
return nil, err return nil, err
} }
firebaseAppClient, err := firebaseApp.Auth(ctx) mg.firebaseAppContext = ctx
mg.firebaseAppClient, err = firebaseApp.Auth(mg.firebaseAppContext)
if err != nil { if err != nil {
logger.Println("FirebaseAppClient error getting Auth client:", err) logger.Println("FirebaseAppClient error getting Auth client:", err)
return nil, err
}
mg.firebase = &firebaseClient{
firebaseAppContext: ctx,
firebaseAppClient: firebaseAppClient,
}
} }
} }
@ -280,113 +288,107 @@ func (mg *Maingate) discoverOpenIdConfiguration(name string, url string) error {
func (mg *Maingate) prepare(context context.Context) (err error) { func (mg *Maingate) prepare(context context.Context) (err error) {
if err := mg.discoverOpenIdConfiguration(AuthPlatformMicrosoft, "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"); err != nil { if err := mg.discoverOpenIdConfiguration(AuthPlatformMicrosoft, "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err := mg.discoverOpenIdConfiguration("google", "https://accounts.google.com/.well-known/openid-configuration"); err != nil { if err := mg.discoverOpenIdConfiguration("google", "https://accounts.google.com/.well-known/openid-configuration"); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
// redis에서 env를 가져온 후에 // redis에서 env를 가져온 후에
mg.mongoClient, err = gocommon.NewMongoClient(context, config.Mongo) mg.mongoClient, err = gocommon.NewMongoClient(context, mg.Mongo, "maingate")
if err != nil { if err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err = mg.mongoClient.MakeUniqueIndices(CollectionCouponUse, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionAuth, map[string]bson.D{
"idrounds": {{Key: "_id", Value: 1}, {Key: "rounds", Value: 1}}, "skonly": {{Key: "sk", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
"platformuid": {{Key: "platform", Value: 1}, {Key: "uid", Value: 1}}, "platformuid": {{Key: "platform", Value: 1}, {Key: "uid", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
// if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
// "emailplatform": {{Key: "email", Value: 1}, {Key: "platform", Value: 1}}, "emailplatform": {{Key: "email", Value: 1}, {Key: "platform", Value: 1}},
// }); err != nil { }); err != nil {
// return logger.ErrorWithCallStack(err) return err
// } }
if err = mg.mongoClient.DropIndex(CollectionLink, "emailplatform"); err != nil {
return logger.ErrorWithCallStack(err) if err = mg.mongoClient.MakeIndices(CollectionWhitelist, map[string]bson.D{
"service": {{Key: "service", Value: 1}},
}); err != nil {
return err
}
if err = mg.mongoClient.MakeIndices(CollectionFile, map[string]bson.D{
"service": {{Key: "service", Value: 1}},
}); err != nil {
return err
} }
if err = mg.mongoClient.MakeIndices(CollectionAccount, map[string]bson.D{ if err = mg.mongoClient.MakeIndices(CollectionAccount, map[string]bson.D{
"accid": {{Key: "accid", Value: 1}}, "accid": {{Key: "accid", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err = mg.mongoClient.MakeUniqueIndices(CollectionFile, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionFile, map[string]bson.D{
"keyonly": {{Key: "key", Value: 1}}, "sk": {{Key: "service", Value: 1}, {Key: "key", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err = mg.mongoClient.MakeExpireIndex(CollectionAccount, int32(config.AccDelTTL)); err != nil {
return logger.ErrorWithCallStack(err)
}
if err = mg.mongoClient.MakeExpireIndex(CollectionLink, int32(config.AccDelTTL)); err != nil {
return logger.ErrorWithCallStack(err)
}
// Delete대신 _ts로 expire시킴. pipeline에 삭제 알려주기 위함
if err = mg.mongoClient.MakeExpireIndex(CollectionWhitelist, 10); err != nil { if err = mg.mongoClient.MakeExpireIndex(CollectionWhitelist, 10); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if *devflag { if err = mg.mongoClient.MakeExpireIndex(CollectionAuth, int32(mg.SessionTTL+300)); err != nil {
// 에러 체크하지 말것 return err
mg.mongoClient.DropIndex(CollectionBlock, "codeaccid")
}
if _, err := mg.mongoClient.Collection(CollectionBlock).Indexes().DropOne(context, "_ts_1"); err == nil {
// 인덱스가 방금 지워졌다.
// 전체 document 제거
logger.Println(mg.mongoClient.Collection(CollectionBlock).Drop(context))
} }
if err = mg.mongoClient.MakeUniqueIndices(CollectionBlock, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionBlock, map[string]bson.D{
"accidend": {{Key: "accid", Value: 1}, {Key: "end", Value: 1}}, "codeaccid": {{Key: "code", Value: 1}, {Key: "accid", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
}
if err = mg.mongoClient.MakeExpireIndex(CollectionBlock, int32(3)); err != nil {
return err
} }
if err = mg.mongoClient.MakeUniqueIndices(CollectionPlatformLoginToken, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionPlatformLoginToken, map[string]bson.D{
"platformauthtoken": {{Key: "platform", Value: 1}, {Key: "key", Value: 1}}, "platformauthtoken": {{Key: "platform", Value: 1}, {Key: "key", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err = mg.mongoClient.MakeExpireIndex(CollectionPlatformLoginToken, int32(config.SessionTTL+300)); err != nil { if err = mg.mongoClient.MakeExpireIndex(CollectionPlatformLoginToken, int32(mg.SessionTTL+300)); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err = mg.mongoClient.MakeUniqueIndices(CollectionUserToken, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionUserToken, map[string]bson.D{
"platformusertoken": {{Key: "platform", Value: 1}, {Key: "userid", Value: 1}}, "platformusertoken": {{Key: "platform", Value: 1}, {Key: "userid", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err = mg.mongoClient.MakeUniqueIndices(CollectionGamepotUserInfo, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionGamepotUserInfo, map[string]bson.D{
"gamepotuserid": {{Key: "gamepotuserid", Value: 1}}, "gamepotuserid": {{Key: "gamepotuserid", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if err = mg.mongoClient.MakeUniqueIndices(CollectionFirebaseUserInfo, map[string]bson.D{ if err = mg.mongoClient.MakeUniqueIndices(CollectionFirebaseUserInfo, map[string]bson.D{
"firebaseuserid": {{Key: "firebaseuserid", Value: 1}}, "firebaseuserid": {{Key: "firebaseuserid", Value: 1}},
}); err != nil { }); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
mg.sessionProvider, err = session.NewProviderWithConfig(context, config.SessionConfig) mg.auths = makeAuthCollection(mg.mongoClient, time.Duration(mg.SessionTTL*int64(time.Second)))
if err != nil {
return logger.ErrorWithCallStack(err)
}
var preall []struct { var preall []struct {
Link string `bson:"link"` Link string `bson:"link"`
@ -395,7 +397,7 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
if err = mg.mongoClient.FindAllAs(CollectionFile, nil, &preall, options.Find().SetProjection(bson.M{ if err = mg.mongoClient.FindAllAs(CollectionFile, nil, &preall, options.Find().SetProjection(bson.M{
"link": 1, "link": 1,
})); err != nil { })); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
for _, pre := range preall { for _, pre := range preall {
@ -410,40 +412,58 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
"_id": pre.Id, "_id": pre.Id,
}, &fulldoc) }, &fulldoc)
if err != nil { if err != nil {
return logger.ErrorWithCallStack(err) return err
} }
err = fulldoc.Save() err = fulldoc.Save()
if err != nil { if err != nil {
return logger.ErrorWithCallStack(err) return err
} }
} }
var whites []whitelistmember
if err := mg.mongoClient.AllAs(CollectionWhitelist, &whites, options.Find().SetReturnKey(false)); err != nil {
return err
}
mg.wl.init(whites)
go watchAuthCollection(context, mg.auths, mg.mongoClient)
go mg.watchWhitelistCollection(context)
return nil return nil
} }
var portptr = flagx.Int("port", 80, "") func whitelistKey(email string, platform string) string {
if strings.HasPrefix(email, "*@") {
// 도메인 전체 허용
return email[2:]
}
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) error { return email
}
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux, prefix string) error {
var allServices []*serviceDescription var allServices []*serviceDescription
if err := mg.mongoClient.AllAs(CollectionService, &allServices, options.Find().SetReturnKey(false)); err != nil { if err := mg.mongoClient.AllAs(CollectionService, &allServices, options.Find().SetReturnKey(false)); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
if len(allServices) > 0 { if len(allServices) > 0 {
only := allServices[0] only := allServices[0]
only.prepare(mg) only.prepare(mg)
only.mustUseChecksum = config.MustUseChecksum
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(only)) atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(only))
} else { } else {
empty := serviceDescription{ empty := serviceDescription{
ServiceDescriptionSummary: ServiceDescriptionSummary{
Id: primitive.NewObjectID(), Id: primitive.NewObjectID(),
},
} }
if *devflag { if *devflag {
host, _ := os.Hostname()
addrs, err := net.InterfaceAddrs() addrs, err := net.InterfaceAddrs()
if err != nil { if err != nil {
return logger.ErrorWithCallStack(err) return err
} }
ipaddr := "127.0.0.1" ipaddr := "127.0.0.1"
for _, addr := range addrs { for _, addr := range addrs {
@ -455,15 +475,13 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
} }
empty.Divisions = map[string]*Division{ empty.Divisions = map[string]*Division{
"default": { host: {
DivisionForUser: DivisionForUser{ DivisionForUser: DivisionForUser{
Priority: 0, Priority: 0,
State: DivisionState_FullOpen, State: DivisionState_FullOpen,
}, },
Urls: bson.M{ Url: fmt.Sprintf("http://%s/warehouse", ipaddr),
"warehouse": fmt.Sprintf("http://%s:%d/warehouse", ipaddr, *portptr),
},
}, },
} }
} }
@ -477,29 +495,21 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
}, options.Update().SetUpsert(true)) }, options.Update().SetUpsert(true))
if err != nil { if err != nil {
return logger.ErrorWithCallStack(err) return err
} }
} }
if *devflag { logger.Println("Service is registered :", mg.service().ServiceCode)
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "/"), func(w http.ResponseWriter, r *http.Request) { serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, mg.service().ServiceCode, "/"), func(w http.ResponseWriter, r *http.Request) {
// mg.service()를 요청마다 불러야 함
mg.service().serveHTTP_dev(w, r)
})
} else {
pattern := gocommon.MakeHttpHandlerPattern(prefix, "/")
logger.Println("pattern registered :", pattern)
serveMux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
// mg.service()를 요청마다 불러야 함
mg.service().serveHTTP(w, r) mg.service().serveHTTP(w, r)
}) })
}
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "api/"), mg.api) serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "api/"), mg.api)
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "query/"), mg.query)
configraw, _ := json.Marshal(config) configraw, _ := json.Marshal(mg.maingateConfig)
var convertedConfig map[string]any var convertedConfig map[string]any
if err := json.Unmarshal(configraw, &convertedConfig); err != nil { if err := json.Unmarshal(configraw, &convertedConfig); err != nil {
return logger.ErrorWithCallStack(err) return err
} }
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "config"), func(w http.ResponseWriter, r *http.Request) { serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "config"), func(w http.ResponseWriter, r *http.Request) {
@ -532,7 +542,7 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
if err := os.MkdirAll("static", os.ModePerm); err != nil { if err := os.MkdirAll("static", os.ModePerm); err != nil {
// 일반 엔드유저한테 오픈할 static 페이지 // 일반 엔드유저한테 오픈할 static 페이지
return logger.ErrorWithCallStack(err) return err
} }
cfsx := http.FileServer(http.Dir("console")) cfsx := http.FileServer(http.Dir("console"))
@ -545,14 +555,6 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
serveMux.Handle(pattern, http.StripPrefix(pattern, staticfs)) serveMux.Handle(pattern, http.StripPrefix(pattern, staticfs))
logger.Println("maingate static registered :", pattern) logger.Println("maingate static registered :", pattern)
fbafs := http.FileServer(http.Dir("fba"))
pattern = gocommon.MakeHttpHandlerPattern(prefix, "fba", "/")
serveMux.Handle(pattern, http.StripPrefix(pattern, fbafs))
logger.Println("google_analytics static registered :", pattern)
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "fba", "fb-ga.min.js"), mg.google_analytics_js)
logger.Println("google_analytics.js static registered :", pattern)
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformGoogle), mg.platform_google_get_login_url) serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformGoogle), mg.platform_google_get_login_url)
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformGoogle), mg.platform_google_authorize) serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformGoogle), mg.platform_google_authorize)
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformGoogle), mg.platform_google_authorize_result) serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformGoogle), mg.platform_google_authorize_result)
@ -574,8 +576,6 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformSteamSDK), mg.platform_steamsdk_authorize) serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformSteamSDK), mg.platform_steamsdk_authorize)
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformHybeim), mg.platform_hybeim_authorize)
go mg.watchServiceCollection(ctx, serveMux, prefix) go mg.watchServiceCollection(ctx, serveMux, prefix)
go mg.watchFileCollection(ctx, serveMux, prefix) go mg.watchFileCollection(ctx, serveMux, prefix)
// fsx := http.FileServer(http.Dir("console")) // fsx := http.FileServer(http.Dir("console"))
@ -585,11 +585,59 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.Serv
return nil return nil
} }
func (mg *Maingate) query(w http.ResponseWriter, r *http.Request) {
defer func() {
s := recover()
if s != nil {
logger.Error(s)
}
}()
defer func() {
io.Copy(io.Discard, r.Body)
r.Body.Close()
}()
queryvals := r.URL.Query()
sk := queryvals.Get("sk")
if len(sk) == 0 {
w.WriteHeader(http.StatusUnauthorized)
return
}
info := mg.auths.Find(sk)
if info == nil {
logger.Println("session key is not valid :", sk)
w.WriteHeader(http.StatusUnauthorized)
return
}
if !*devflag {
apitoken := r.Header.Get("MG-X-API-TOKEN")
if len(apitoken) == 0 {
logger.Println("MG-X-API-TOKEN is missing")
w.WriteHeader(http.StatusBadRequest)
return
}
apitokenObj, _ := primitive.ObjectIDFromHex(apitoken)
if !mg.service().isValidToken(apitokenObj) {
logger.Println("MG-X-API-TOKEN is invalid :", apitoken)
w.WriteHeader(http.StatusBadRequest)
return
}
}
bt, _ := json.Marshal(info)
w.Write(bt)
}
func (mg *Maingate) GeneratePlatformLoginNonceKey() string { func (mg *Maingate) GeneratePlatformLoginNonceKey() string {
const allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" const allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, 52) b := make([]byte, 52)
for i := range b { for i := range b {
b[i] = allowed[r.Intn(len(allowed))] b[i] = allowed[rand.Intn(len(allowed))]
} }
return string(b) return string(b)
} }
@ -603,7 +651,7 @@ func (mg *Maingate) GetUserBrowserInfo(r *http.Request) (string, error) {
cookie, err := r.Cookie("ActionSquareSessionExtraInfo") cookie, err := r.Cookie("ActionSquareSessionExtraInfo")
if err != nil { if err != nil {
return "", logger.ErrorWithCallStack(err) return "", err
} }
//requestinfo := fmt.Sprintf("%s_%s", cookie.Value, host) //-- RemoteAddr체크는 로드밸런서 IP 찍히는 문제 때문에 제외한다. //requestinfo := fmt.Sprintf("%s_%s", cookie.Value, host) //-- RemoteAddr체크는 로드밸런서 IP 찍히는 문제 때문에 제외한다.
@ -625,7 +673,7 @@ func (mg *Maingate) setUserToken(info usertokeninfo) error {
"accesstoken_expire_time": info.accesstoken_expire_time, "accesstoken_expire_time": info.accesstoken_expire_time,
}, },
}, options.Update().SetUpsert(true)) }, options.Update().SetUpsert(true))
return logger.ErrorWithCallStack(err) return err
} }
func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo string) (usertokeninfo, error) { func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo string) (usertokeninfo, error) {
@ -650,7 +698,7 @@ func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo
updatetime, ok := found["lastupdate"].(int64) updatetime, ok := found["lastupdate"].(int64)
if !ok || time.Now().Unix()-updatetime < config.Autologin_ttl { if !ok || time.Now().Unix()-updatetime < mg.maingateConfig.Autologin_ttl {
info.platform = platform info.platform = platform
info.userid = userid info.userid = userid
info.brinfo = brinfo info.brinfo = brinfo
@ -699,8 +747,6 @@ func (mg *Maingate) updateUserinfo(info usertokeninfo) (bool, string, string) {
success, userid, email = mg.platform_google_getuserinfo(info) success, userid, email = mg.platform_google_getuserinfo(info)
case AuthPlatformSteamSDK: case AuthPlatformSteamSDK:
success, userid, email = mg.platform_steamsdk_getuserinfo(info) success, userid, email = mg.platform_steamsdk_getuserinfo(info)
case AuthPlatformHybeim:
success, userid, email = mg.platform_hybeim_getuserinfo(info)
case AuthPlatformFirebaseAuth: case AuthPlatformFirebaseAuth:
success, userid, email = mg.platform_firebase_getuserinfo(info) success, userid, email = mg.platform_firebase_getuserinfo(info)
} }
@ -910,22 +956,3 @@ func JWTparseCode(keyurl string, code string) (string, string, string) {
//--- nonce 체크 필요하다. //--- nonce 체크 필요하다.
return claims["sub"].(string), email, nonce return claims["sub"].(string), email, nonce
} }
func (mg *Maingate) google_analytics_js(w http.ResponseWriter, r *http.Request) {
fgaconfig := Firebase_Google_Analytics_JS_SDK_Config{
FGA_apiKey: config.FGA_apiKey,
FGA_authDomain: config.FGA_authDomain,
FGA_databaseURL: config.FGA_databaseURL,
FGA_projectId: config.FGA_projectId,
FGA_storageBucket: config.FGA_storageBucket,
FGA_messagingSenderId: config.FGA_messagingSenderId,
FGA_appId: config.FGA_appId,
FGA_measurementId: config.FGA_measurementId,
}
parsedTemplate, _ := template.ParseFiles("template/fb-ga.min.js")
err := parsedTemplate.Execute(w, fgaconfig)
if err != nil {
logger.Error("Error executing template :", err)
return
}
}

View File

@ -95,8 +95,8 @@ func (mg *Maingate) platform_apple_get_login_url(w http.ResponseWriter, r *http.
} }
params := url.Values{} params := url.Values{}
params.Add("client_id", config.AppleCientId) params.Add("client_id", mg.AppleCientId)
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformApple) params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformApple)
params.Add("response_type", "code id_token") params.Add("response_type", "code id_token")
params.Add("scope", "name email") params.Add("scope", "name email")
@ -146,7 +146,7 @@ func (mg *Maingate) platform_apple_authorize(w http.ResponseWriter, r *http.Requ
} }
http.SetCookie(w, &cookie) http.SetCookie(w, &cookie)
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformApple, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다. http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformApple, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
} }
func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *http.Request) { func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *http.Request) {
@ -208,17 +208,17 @@ func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *ht
} }
// Generate the client secret used to authenticate with Apple's validation servers // Generate the client secret used to authenticate with Apple's validation servers
secret, err := generateClientSecret(config.ApplePrivateKey, config.AppleTeamId, config.AppleServiceId, config.AppleKeyId) secret, err := generateClientSecret(mg.ApplePrivateKey, mg.AppleTeamId, mg.AppleServiceId, mg.AppleKeyId)
if err != nil { if err != nil {
logger.Error("error generating secret: ", err) logger.Error("error generating secret: ", err)
return return
} }
vReq := Apple_WebValidationTokenRequest{ vReq := Apple_WebValidationTokenRequest{
ClientID: config.AppleServiceId, ClientID: mg.AppleServiceId,
ClientSecret: secret, ClientSecret: secret,
Code: code, Code: code,
RedirectURI: config.RedirectBaseUrl + "/authorize/" + AuthPlatformApple, // This URL must be validated with apple in your service RedirectURI: mg.RedirectBaseUrl + "/authorize/" + AuthPlatformApple, // This URL must be validated with apple in your service
} }
var resp Apple_ValidationResponse var resp Apple_ValidationResponse
@ -268,14 +268,14 @@ func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *ht
func (mg *Maingate) platform_apple_getuserinfo(refreshToken string) (bool, string, string) { func (mg *Maingate) platform_apple_getuserinfo(refreshToken string) (bool, string, string) {
//=================================RefreshToken을 사용해서 정보 가져 온다. 이미 인증된 사용자의 업데이트 목적 //=================================RefreshToken을 사용해서 정보 가져 온다. 이미 인증된 사용자의 업데이트 목적
secret, err := generateClientSecret(config.ApplePrivateKey, config.AppleTeamId, config.AppleServiceId, config.AppleKeyId) secret, err := generateClientSecret(mg.ApplePrivateKey, mg.AppleTeamId, mg.AppleServiceId, mg.AppleKeyId)
if err != nil { if err != nil {
logger.Error("error generating secret: ", err) logger.Error("error generating secret: ", err)
return false, "", "" return false, "", ""
} }
vReqRefreshToken := Apple_WebRefreshTokenRequest{ vReqRefreshToken := Apple_WebRefreshTokenRequest{
ClientID: config.AppleServiceId, ClientID: mg.AppleServiceId,
ClientSecret: secret, ClientSecret: secret,
RefreshToken: refreshToken, RefreshToken: refreshToken,
} }

View File

@ -3,7 +3,6 @@ package core
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
@ -147,11 +146,6 @@ func (mg *Maingate) platform_firebaseauth_authorize_sdk(w http.ResponseWriter, r
} }
func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, brinfo, code, state, cookieSessionKey, memberId, nickname, provider, providerId, email, photourl, phonenumber string) (bool, string) { func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, brinfo, code, state, cookieSessionKey, memberId, nickname, provider, providerId, email, photourl, phonenumber string) (bool, string) {
if mg.firebase == nil {
logger.Println("mg.firebase is nil. check 'firebase_admin_sdk_credentialfile' config or 'authtype' parameter")
w.WriteHeader(http.StatusBadRequest)
return false, ""
}
found, err := mg.mongoClient.FindOne(CollectionPlatformLoginToken, bson.M{ found, err := mg.mongoClient.FindOne(CollectionPlatformLoginToken, bson.M{
"platform": AuthPlatformFirebaseAuth, "platform": AuthPlatformFirebaseAuth,
@ -194,7 +188,7 @@ func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, b
return false, "" return false, ""
} }
_, err = mg.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.firebaseAppContext, code) _, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, code)
if err != nil { if err != nil {
log.Println("error verifying ID token:", err) log.Println("error verifying ID token:", err)
return false, "" return false, ""
@ -248,10 +242,6 @@ func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, b
} }
func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, string, string) { func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, string, string) {
if mg.firebase == nil {
logger.Println("mg.firebase is nil. check 'firebase_admin_sdk_credentialfile' config or 'authtype' parameter")
return false, "", ""
}
found, err := mg.mongoClient.FindOne(CollectionFirebaseUserInfo, bson.M{ found, err := mg.mongoClient.FindOne(CollectionFirebaseUserInfo, bson.M{
"firebaseuserid": info.userid, "firebaseuserid": info.userid,
@ -266,16 +256,13 @@ func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, str
return false, "", "" return false, "", ""
} }
_, err = mg.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.firebaseAppContext, info.token) _, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, info.token)
if err != nil { if err != nil {
log.Println("error verifying ID token:", err) log.Println("error verifying ID token:", err)
return false, "", "" return false, "", ""
} }
tempEmail := found["firebaseemail"].(string) tempEmail := found["firebaseemail"].(string)
if found["firebaseprovider"].(string) == "guest" {
tempEmail = fmt.Sprintf("%s@guest.flag", info.userid)
}
return true, info.userid, tempEmail return true, info.userid, tempEmail

View File

@ -84,9 +84,9 @@ func (mg *Maingate) platform_google_get_login_url(w http.ResponseWriter, r *http
} }
params := url.Values{} params := url.Values{}
params.Add("client_id", config.GoogleClientId) params.Add("client_id", mg.GoogleClientId)
params.Add("response_type", "code") params.Add("response_type", "code")
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle) params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email") params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email")
params.Add("access_type", "offline") params.Add("access_type", "offline")
params.Add("prompt", "consent") params.Add("prompt", "consent")
@ -140,7 +140,7 @@ func (mg *Maingate) platform_google_authorize(w http.ResponseWriter, r *http.Req
} }
http.SetCookie(w, &cookie2) http.SetCookie(w, &cookie2)
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformGoogle, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다. http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformGoogle, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
} }
func (mg *Maingate) platform_google_authorize_result(w http.ResponseWriter, r *http.Request) { func (mg *Maingate) platform_google_authorize_result(w http.ResponseWriter, r *http.Request) {
@ -211,9 +211,9 @@ func (mg *Maingate) platform_google_authorize_result(w http.ResponseWriter, r *h
//================= //=================
params := url.Values{} params := url.Values{}
params.Add("client_id", config.GoogleClientId) params.Add("client_id", mg.GoogleClientId)
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle) params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
params.Add("client_secret", config.GoogleClientSecret) params.Add("client_secret", mg.GoogleClientSecret)
params.Add("code", code) params.Add("code", code)
params.Add("grant_type", "authorization_code") params.Add("grant_type", "authorization_code")
@ -285,9 +285,9 @@ func (mg *Maingate) platform_google_getuserinfo(info usertokeninfo) (bool, strin
if time.Now().Unix() > info.accesstoken_expire_time { if time.Now().Unix() > info.accesstoken_expire_time {
params := url.Values{} params := url.Values{}
params.Add("client_id", config.GoogleClientId) params.Add("client_id", mg.GoogleClientId)
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle) params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
params.Add("client_secret", config.GoogleClientSecret) params.Add("client_secret", mg.GoogleClientSecret)
params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email") params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email")
params.Add("refresh_token", info.token) params.Add("refresh_token", info.token)
params.Add("grant_type", "refresh_token") params.Add("grant_type", "refresh_token")

View File

@ -1,198 +0,0 @@
package core
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"time"
"repositories.action2quare.com/ayo/gocommon/logger"
)
type HybeImSDKAuthInfo struct {
UserHybeimid string `json:"imid"`
UserLoginVerifyToken string `json:"loginVerifyToken"`
}
type HybeImSDKLoginAuthInfo struct {
ServiceId string `json:"serviceId"`
UserLoginVerifyToken string `json:"loginVerifyToken"`
}
type Hiveim_LoginVerifyResult struct {
State string `json:"state"`
ImId string `json:"imId"`
Provider string `json:"provider"`
Os string `json:"os"`
AppStore string `json:"appStore"`
UserBlockInfo []Hiveim_UserBlockInfo `json:"blocks"`
}
type Hiveim_UserBlockInfo struct {
BlockId int `json:"blockId"`
ReasonId int `json:"reasonId"`
BlockedAt int64 `json:"blockedAt"`
ExpireAt int64 `json:"expireAt"`
Permanent bool `json:"permanent"`
}
type Hiveim_LoginValidationResponse struct {
ResultCode string `json:"resultCode"`
ResultMessage string `json:"resultMessage"`
ResultData Hiveim_LoginVerifyResult `json:"resultData"`
}
func (mg *Maingate) platform_hybeim_authorize(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
brinfo, err := mg.GetUserBrowserInfo(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
logger.Error(err)
return
}
var authinfo HybeImSDKAuthInfo
err = json.NewDecoder(r.Body).Decode(&authinfo)
if err != nil {
logger.Println("authinfo decoding fail:", err)
w.WriteHeader(http.StatusBadRequest)
return
}
var resultcode string
var blockinfo Hiveim_UserBlockInfo
if !*noauth {
err, resultcode, blockinfo = authenticateHybeImUser(config.HybeImProjectIdstring, config.HybeImServiceIdstring, config.HybeImAccessKey, config.HybeImEndPoint, authinfo.UserHybeimid, authinfo.UserLoginVerifyToken)
}
// https://hybeim.gitbook.io/im-assemble/api/im-assemble-s2s-api#login-verify
// SUCCESS : 성공
// INVALID_LOGIN_VERIFY_TOKEN : login 인증 토큰 오류
// LOGIN_VERIFY_EXPIRED : login 인증 토큰 만료
// INVALID_SERVICE_ID : 유효 하지 않은 서비스 id
// WITHDRAWAL_ACCOUNT : 탈퇴 대기 상태 유저
// RELOGIN_REQUIRED : 로그인 데이터에 문제가 있어 다시 로그인 해야 되는 경우
// INTERNAL_SERVER_ERROR : 서버 오류
if err == nil && resultcode == "SUCCESS" {
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
var info usertokeninfo
info.platform = AuthPlatformHybeim
info.userid = authinfo.UserHybeimid
info.token = authinfo.UserLoginVerifyToken
info.brinfo = brinfo
//info.accesstoken = respReferesh.AccessToken
info.accesstoken_expire_time = acceestoken_expire_time
mg.setUserToken(info)
params := url.Values{}
params.Add("id", authinfo.UserHybeimid)
params.Add("authtype", AuthPlatformHybeim)
w.Write([]byte("?" + params.Encode()))
//http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
return
} else {
params := url.Values{}
params.Add("resultcode", resultcode)
if resultcode == "BLOCKED" {
blockinfoBytes, _ := json.Marshal(blockinfo)
blockinfostr := string(blockinfoBytes)
params.Add("blockinfo", blockinfostr)
}
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("?" + params.Encode()))
}
// logger.Println(err)
// http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
}
func authenticateHybeImUser(projectid, serviceid, accesskey, endpoint, imid, UserLoginVerifyToken string) (error, string, Hiveim_UserBlockInfo) {
// endpoint
// qa = https://api-qa.pub-dev.hybegames.io
// prod = https://api.hybegames.com
verifyurl := endpoint + "/member/api-game/v1/auth/login/verify"
var param HybeImSDKLoginAuthInfo
param.UserLoginVerifyToken = UserLoginVerifyToken
param.ServiceId = serviceid
dat, err := json.Marshal(param)
if err != nil {
panic(err)
}
var respReferesh Hiveim_LoginValidationResponse
req, err := http.NewRequest("POST", verifyurl, bytes.NewBuffer(dat))
if err != nil {
panic(err)
}
req.Header.Add("X-Auth-Access-Key", accesskey)
req.Header.Add("X-Req-Pjid", projectid)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
defer func() {
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
}()
var blockinfo Hiveim_UserBlockInfo
body, e := ioutil.ReadAll(resp.Body)
if e != nil {
return e, "", blockinfo
}
json.Unmarshal(body, &respReferesh)
//fmt.Println(string(body))
var doc map[string]interface{}
if err := json.Unmarshal(body, &doc); err != nil {
return err, respReferesh.ResultCode, blockinfo
}
// if respReferesh.ResultData.State != "NORMAL" {
// return errors.New("higveimSDK: State is not NORMAL"), respReferesh.ResultCode, blockinfo
// }
if respReferesh.ResultData.Provider != "STEAM" {
return errors.New("higveimSDK: Provider is not STEAM"), respReferesh.ResultCode, blockinfo
}
if respReferesh.ResultData.ImId != imid {
return errors.New("higveimSDK: ImId is not match"), respReferesh.ResultCode, blockinfo
}
if respReferesh.ResultCode == "SUCCESS" {
if respReferesh.ResultData.State == "BLOCKED" && len(respReferesh.ResultData.UserBlockInfo) > 0 {
blockinfo = respReferesh.ResultData.UserBlockInfo[0]
return nil, "BLOCKED", blockinfo
}
}
return nil, respReferesh.ResultCode, blockinfo
}
func (mg *Maingate) platform_hybeim_getuserinfo(info usertokeninfo) (bool, string, string) {
// Hybeim ( Steam )도 이메일 정보를 받을수 없기 때문에 userid로 리턴한다.
dummyEmail := fmt.Sprintf("%s@hibeim.id", info.userid)
return true, info.userid, dummyEmail
}

View File

@ -83,9 +83,9 @@ func (mg *Maingate) platform_microsoft_get_login_url(w http.ResponseWriter, r *h
} }
params := url.Values{} params := url.Values{}
params.Add("client_id", config.MicrosoftClientId) params.Add("client_id", mg.MicrosoftClientId)
params.Add("response_type", "code") params.Add("response_type", "code")
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft) params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
params.Add("response_mode", "query") params.Add("response_mode", "query")
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read") params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
@ -127,7 +127,7 @@ func (mg *Maingate) platform_microsoft_authorize(w http.ResponseWriter, r *http.
} }
http.SetCookie(w, &cookie) http.SetCookie(w, &cookie)
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformMicrosoft, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다. http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformMicrosoft, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
} }
func (mg *Maingate) platform_microsoft_authorize_result(w http.ResponseWriter, r *http.Request) { func (mg *Maingate) platform_microsoft_authorize_result(w http.ResponseWriter, r *http.Request) {
@ -191,13 +191,13 @@ func (mg *Maingate) platform_microsoft_authorize_result(w http.ResponseWriter, r
//================= //=================
params := url.Values{} params := url.Values{}
params.Add("client_id", config.MicrosoftClientId) params.Add("client_id", mg.MicrosoftClientId)
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft) params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
params.Add("code", code) params.Add("code", code)
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read") params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
params.Add("grant_type", "authorization_code") params.Add("grant_type", "authorization_code")
params.Add("client_secret", config.MicrosoftClientSecret) params.Add("client_secret", mg.MicrosoftClientSecret)
var respReferesh Microsoft_ValidationResponse var respReferesh Microsoft_ValidationResponse
acceestoken_expire_time := time.Now().Unix() acceestoken_expire_time := time.Now().Unix()
@ -263,13 +263,13 @@ func (mg *Maingate) platform_microsoft_getuserinfo(info usertokeninfo) (bool, st
if time.Now().Unix() > info.accesstoken_expire_time { if time.Now().Unix() > info.accesstoken_expire_time {
params := url.Values{} params := url.Values{}
params.Add("client_id", config.MicrosoftClientId) params.Add("client_id", mg.MicrosoftClientId)
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft) params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
params.Add("refresh_token", info.token) params.Add("refresh_token", info.token)
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read") params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
params.Add("grant_type", "refresh_token") params.Add("grant_type", "refresh_token")
params.Add("client_secret", config.MicrosoftClientSecret) params.Add("client_secret", mg.MicrosoftClientSecret)
var respReferesh Microsoft_ValidationResponse var respReferesh Microsoft_ValidationResponse
acceestoken_expire_time := time.Now().Unix() acceestoken_expire_time := time.Now().Unix()

View File

@ -39,7 +39,10 @@ func (mg *Maingate) platform_steamsdk_authorize(w http.ResponseWriter, r *http.R
return return
} }
if err := authenticateSteamUser(config.SteamPublisherAuthKey, config.SteamAppId, authinfo.UserSteamId, authinfo.UserAuthToken); err == nil { err = authenticateSteamUser(mg.SteamPublisherAuthKey, mg.SteamAppId, authinfo.UserSteamId, authinfo.UserAuthToken)
if err == nil {
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix() acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
var info usertokeninfo var info usertokeninfo
@ -114,8 +117,9 @@ func authenticateSteamUser(pubkey, appid, playerid, ticket string) error {
} }
func (mg *Maingate) platform_steamsdk_getuserinfo(info usertokeninfo) (bool, string, string) { func (mg *Maingate) platform_steamsdk_getuserinfo(info usertokeninfo) (bool, string, string) {
// Steam은 이메일 정보를 받을수 없기 때문에 userid로 리턴한다.
dummyEmail := fmt.Sprintf("%s@steam.id", info.userid) // Steam은 이메일 정보를 받을수 없기 때문에 dummy임시 주소 할당하여 리턴한다.
dummyEmail := fmt.Sprintf("__dummy_%s@steamtemp__", info.userid)
return true, info.userid, dummyEmail return true, info.userid, dummyEmail
} }

View File

@ -123,7 +123,7 @@ func (mg *Maingate) platform_twitter_authorize(w http.ResponseWriter, r *http.Re
} }
http.SetCookie(w, &cookie) http.SetCookie(w, &cookie)
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformTwitter, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다. http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformTwitter, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
} }
func (mg *Maingate) platform_twitter_authorize_result(w http.ResponseWriter, r *http.Request) { func (mg *Maingate) platform_twitter_authorize_result(w http.ResponseWriter, r *http.Request) {
@ -249,7 +249,7 @@ func (mg *Maingate) platform_twitter_getuserinfo(token, secret string) (bool, st
} }
func (mg *Maingate) CallTwitterAPI_WithAPPKey(requesturl, method, nonce string) string { func (mg *Maingate) CallTwitterAPI_WithAPPKey(requesturl, method, nonce string) string {
return mg.CallTwitterAPI(requesturl, method, config.TwitterOAuthKey, config.TwitterOAuthSecret, nonce) return mg.CallTwitterAPI(requesturl, method, mg.TwitterOAuthKey, mg.TwitterOAuthSecret, nonce)
} }
func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret, nonce string) string { func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret, nonce string) string {
@ -272,8 +272,8 @@ func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret
//vals.Add("oauth_callback", "actionclient://callback") //vals.Add("oauth_callback", "actionclient://callback")
//vals.Add("oauth_callback", "http://127.0.0.1:7770/auth") //vals.Add("oauth_callback", "http://127.0.0.1:7770/auth")
vals.Add("oauth_callback", config.RedirectBaseUrl+"/authorize/"+AuthPlatformTwitter) vals.Add("oauth_callback", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformTwitter)
vals.Add("oauth_consumer_key", config.TwitterCustomerKey) vals.Add("oauth_consumer_key", mg.TwitterCustomerKey)
vals.Add("oauth_token", oauth_token) vals.Add("oauth_token", oauth_token)
vals.Add("oauth_signature_method", "HMAC-SHA1") vals.Add("oauth_signature_method", "HMAC-SHA1")
vals.Add("oauth_timestamp", strconv.Itoa(int(time.Now().Unix()))) vals.Add("oauth_timestamp", strconv.Itoa(int(time.Now().Unix())))
@ -282,7 +282,7 @@ func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret
parameterString := strings.Replace(vals.Encode(), "+", "%20", -1) parameterString := strings.Replace(vals.Encode(), "+", "%20", -1)
signatureBase := strings.ToUpper(method) + "&" + url.QueryEscape(strings.Split(requesturl, "?")[0]) + "&" + url.QueryEscape(parameterString) signatureBase := strings.ToUpper(method) + "&" + url.QueryEscape(strings.Split(requesturl, "?")[0]) + "&" + url.QueryEscape(parameterString)
signingKey := url.QueryEscape(config.TwitterCustomerSecret) + "&" + url.QueryEscape(oauth_secret) signingKey := url.QueryEscape(mg.TwitterCustomerSecret) + "&" + url.QueryEscape(oauth_secret)
signature := calculateTwitterSignature(signatureBase, signingKey) signature := calculateTwitterSignature(signatureBase, signingKey)
headerString := "OAuth oauth_callback=\"" + url.QueryEscape(vals.Get("oauth_callback")) + "\", oauth_consumer_key=\"" + url.QueryEscape(vals.Get("oauth_consumer_key")) + "\", oauth_nonce=\"" + url.QueryEscape(vals.Get("oauth_nonce")) + headerString := "OAuth oauth_callback=\"" + url.QueryEscape(vals.Get("oauth_callback")) + "\", oauth_consumer_key=\"" + url.QueryEscape(vals.Get("oauth_consumer_key")) + "\", oauth_nonce=\"" + url.QueryEscape(vals.Get("oauth_nonce")) +

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@ package core
import ( import (
"context" "context"
"encoding/hex" "encoding/hex"
"net/http"
"os" "os"
"path" "path"
"sync/atomic" "sync/atomic"
@ -18,6 +19,14 @@ import (
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
) )
type authPipelineDocument struct {
OperationType string `bson:"operationType"`
DocumentKey struct {
Id primitive.ObjectID `bson:"_id"`
} `bson:"documentKey"`
Authinfo *gocommon.Authinfo `bson:"fullDocument"`
}
type servicePipelineDocument struct { type servicePipelineDocument struct {
OperationType string `bson:"operationType"` OperationType string `bson:"operationType"`
DocumentKey struct { DocumentKey struct {
@ -34,7 +43,103 @@ type filePipelineDocument struct {
File *FileDocumentDesc `bson:"fullDocument"` File *FileDocumentDesc `bson:"fullDocument"`
} }
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) { type whilelistPipelineDocument struct {
OperationType string `bson:"operationType"`
DocumentKey struct {
Id primitive.ObjectID `bson:"_id"`
} `bson:"documentKey"`
Member *whitelistmember `bson:"fullDocument"`
}
func (mg *Maingate) watchWhitelistCollection(parentctx context.Context) {
defer func() {
s := recover()
if s != nil {
logger.Error(s)
}
}()
matchStage := bson.D{
{
Key: "$match", Value: bson.D{
{Key: "operationType", Value: bson.D{
{Key: "$in", Value: bson.A{
"update",
"insert",
}},
}},
},
}}
projectStage := bson.D{
{
Key: "$project", Value: bson.D{
{Key: "documentKey", Value: 1},
{Key: "operationType", Value: 1},
{Key: "fullDocument", Value: 1},
},
},
}
var stream *mongo.ChangeStream
var err error
var ctx context.Context
for {
if stream == nil {
stream, err = mg.mongoClient.Watch(CollectionWhitelist, mongo.Pipeline{matchStage, projectStage})
if err != nil {
logger.Error("watchWhitelistCollection watch failed :", err)
time.Sleep(time.Minute)
continue
}
ctx = context.TODO()
}
changed := stream.TryNext(ctx)
if ctx.Err() != nil {
logger.Error("watchWhitelistCollection stream.TryNext failed. process should be restarted! :", ctx.Err().Error())
break
}
if changed {
var data whilelistPipelineDocument
if err := stream.Decode(&data); err == nil {
ot := data.OperationType
switch ot {
case "insert":
// 새 화이트리스트 멤버
mg.service().wl.add(data.Member)
case "update":
if data.Member.Expired != 0 {
logger.Println("whitelist member is removed :", *data.Member)
mg.service().wl.remove(data.Member.Email, data.Member.Platform)
} else {
logger.Println("whitelist member is updated :", *data.Member)
mg.service().wl.add(data.Member)
}
}
} else {
logger.Error("watchWhitelistCollection stream.Decode failed :", err)
}
} else if stream.Err() != nil || stream.ID() == 0 {
select {
case <-ctx.Done():
logger.Println("watchWhitelistCollection is done")
stream.Close(ctx)
return
case <-time.After(time.Second):
logger.Error("watchWhitelistCollection stream error :", stream.Err())
stream.Close(ctx)
stream = nil
}
} else {
time.Sleep(time.Second)
}
}
}
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
defer func() { defer func() {
s := recover() s := recover()
if s != nil { if s != nil {
@ -119,7 +224,7 @@ func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux goco
} }
} }
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) { func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
defer func() { defer func() {
s := recover() s := recover()
if s != nil { if s != nil {
@ -213,3 +318,87 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux g
} }
} }
} }
func watchAuthCollection(parentctx context.Context, ac *gocommon.AuthCollection, mongoClient gocommon.MongoClient) {
defer func() {
s := recover()
if s != nil {
logger.Error(s)
}
}()
matchStage := bson.D{
{
Key: "$match", Value: bson.D{
{Key: "operationType", Value: bson.D{
{Key: "$in", Value: bson.A{
"delete",
"insert",
"update",
}},
}},
},
}}
projectStage := bson.D{
{
Key: "$project", Value: bson.D{
{Key: "documentKey", Value: 1},
{Key: "operationType", Value: 1},
{Key: "fullDocument", Value: 1},
},
},
}
var stream *mongo.ChangeStream
var err error
var ctx context.Context
for {
if stream == nil {
stream, err = mongoClient.Watch(CollectionAuth, mongo.Pipeline{matchStage, projectStage})
if err != nil {
logger.Error("watchAuthCollection watch failed :", err)
time.Sleep(time.Minute)
continue
}
ctx = context.TODO()
}
changed := stream.TryNext(ctx)
if ctx.Err() != nil {
logger.Error("watchAuthCollection stream.TryNext failed. process should be restarted! :", ctx.Err().Error())
break
}
if changed {
var data authPipelineDocument
if err := stream.Decode(&data); err == nil {
ot := data.OperationType
switch ot {
case "insert":
ac.AddRaw(&mongoAuthCell{src: data.Authinfo})
case "update":
ac.AddRaw(&mongoAuthCell{src: data.Authinfo})
case "delete":
ac.RemoveByAccId(data.DocumentKey.Id)
}
} else {
logger.Error("watchAuthCollection stream.Decode failed :", err)
}
} else if stream.Err() != nil || stream.ID() == 0 {
select {
case <-ctx.Done():
logger.Println("watchAuthCollection is done")
stream.Close(ctx)
return
case <-time.After(time.Second):
logger.Error("watchAuthCollection stream error :", stream.Err())
stream.Close(ctx)
stream = nil
}
} else {
time.Sleep(time.Second)
}
}
}

537
fba/js.js

File diff suppressed because one or more lines are too long

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript" src="./fb-ga.min.js">
</script>
</body>
</html>
<!-- <body> -->
<!-- <body onload="window.FBA.TrackLogEvent('DESKTOP-TEST');"> -->
<!-- <script type="cjs" src="./fb-ga.rollup.js"> -->

64
go.mod
View File

@ -1,38 +1,34 @@
module repositories.action2quare.com/ayo/maingate module repositories.action2quare.com/ayo/maingate
go 1.22.1 go 1.18
require ( require (
firebase.google.com/go v3.13.0+incompatible firebase.google.com/go v3.13.0+incompatible
github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible
go.mongodb.org/mongo-driver v1.11.7 go.mongodb.org/mongo-driver v1.11.7
google.golang.org/api v0.157.0 google.golang.org/api v0.128.0
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86 repositories.action2quare.com/ayo/gocommon v0.0.0-20230801051747-b501160efc3b
) )
require ( require (
cloud.google.com/go v0.111.0 // indirect cloud.google.com/go v0.110.2 // indirect
cloud.google.com/go/compute v1.23.3 // indirect cloud.google.com/go/compute v1.20.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/firestore v1.14.0 // indirect cloud.google.com/go/firestore v1.10.0 // indirect
cloud.google.com/go/iam v1.1.5 // indirect cloud.google.com/go/iam v1.1.1 // indirect
cloud.google.com/go/longrunning v0.5.4 // indirect cloud.google.com/go/longrunning v0.5.1 // indirect
cloud.google.com/go/storage v1.30.1 // indirect cloud.google.com/go/storage v1.30.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/s2a-go v0.1.7 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/google/uuid v1.5.0 // indirect github.com/google/s2a-go v0.1.4 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
github.com/klauspost/compress v1.16.6 // indirect github.com/klauspost/compress v1.16.6 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect github.com/montanaflynn/stats v0.7.1 // indirect
github.com/pires/go-proxyproto v0.7.0 // indirect github.com/pires/go-proxyproto v0.7.0 // indirect
@ -42,22 +38,20 @@ require (
github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect golang.org/x/crypto v0.10.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect golang.org/x/net v0.11.0 // indirect
go.opentelemetry.io/otel v1.21.0 // indirect golang.org/x/oauth2 v0.9.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect golang.org/x/sync v0.3.0 // indirect
go.opentelemetry.io/otel/trace v1.21.0 // indirect golang.org/x/sys v0.9.0 // indirect
golang.org/x/crypto v0.18.0 // indirect golang.org/x/text v0.10.0 // indirect
golang.org/x/net v0.20.0 // indirect golang.org/x/time v0.3.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
golang.org/x/sync v0.6.0 // indirect google.golang.org/appengine v1.6.7 // indirect
golang.org/x/sys v0.16.0 // indirect google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect
golang.org/x/text v0.14.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect
golang.org/x/time v0.5.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
google.golang.org/appengine v1.6.8 // indirect google.golang.org/grpc v1.56.0 // indirect
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect google.golang.org/protobuf v1.30.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/protobuf v1.32.0 // indirect
) )
replace repositories.action2quare.com/ayo/maingate => ./

178
go.sum
View File

@ -1,27 +1,34 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU= cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA=
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw= cloud.google.com/go/firestore v1.10.0 h1:FG5C49ukKKqyljY+XNRZGae1HZaiVe7aoqi2BipnBuM=
cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= cloud.google.com/go/firestore v1.10.0/go.mod h1:eAeoQCV8F35Mcy4k8ZrQbcSYZOayIwoiU7ZJ6xzH1+o=
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg= cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI=
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI= cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4= firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs= firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -30,16 +37,11 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
@ -50,13 +52,16 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -73,17 +78,19 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk= github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
@ -105,14 +112,17 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
@ -131,24 +141,15 @@ go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJv
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY= go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -156,48 +157,55 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs=
golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -207,29 +215,35 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
google.golang.org/api v0.157.0 h1:ORAeqmbrrozeyw5NjnMxh7peHO0UzV4wWYSwZeCUb20= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.157.0/go.mod h1:+z4v4ufbZ1WEpld6yMGHyggs+PmAHiaLNj5ytP3N01g= google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg=
google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.56.0 h1:+y7Bs8rtMd07LeXmL3NxcTLn7mUkbKZqEpPhMNkwJEE=
google.golang.org/grpc v1.56.0/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -241,16 +255,40 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86 h1:vP0mVST68cw14fI/af3Xp1ZQoYjkNGK4S0zji1BVfSI= repositories.action2quare.com/ayo/gocommon v0.0.0-20230612013915-5950ff4bb82e h1:m0jo1r+2NtBfxwj92e6EVaBZpzTDT6Hq7D93vWO4h9Y=
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86/go.mod h1:XA8+hQtUNh956T+kAbJKkUtMl5HUWj83knvdBvvPS5s= repositories.action2quare.com/ayo/gocommon v0.0.0-20230612013915-5950ff4bb82e/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230614091557-9b877d9a732c h1:fhCuu0jFps8T1sN8hO0fGnatvNDW6VwM96PV26EA3T4=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230614091557-9b877d9a732c/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230616031450-0b2c9351a717 h1:WrkkEWN3bh1QAulNJZjAiwXx2aPAj39OoIyJFUXmDaE=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230616031450-0b2c9351a717/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230616032216-378bc19f3742 h1:qEbzwVDz1w2ewNHu+vipzV+a804wmwRWe+0vnhCbJr4=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230616032216-378bc19f3742/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230620005911-15ba3e93d621 h1:9Hzdn13l9U0RJn9mMXsZQr+jsmsgy3zQFsBHPSOJnxM=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230620005911-15ba3e93d621/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621051330-0d8752e66161 h1:sgixcFwdLOqcvwqTaKcsMEepXsLmNEgaybyur3QHRgk=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621051330-0d8752e66161/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621052811-06ef97f11d22 h1:DImSGNxZrc+Q4WlS1OKMsLAScEfDYLX4XMJdjAaVnXc=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230621052811-06ef97f11d22/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710081612-3024a17b540f h1:MMA/6fqn76zSOkUQzG8v+IbWvrtY1mXN5xF1WOZonVc=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710081612-3024a17b540f/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710084625-dd05ebf6ceb9 h1:dizJeTf3xt7wEeq72sYqlgdy7an8kezA6JuqALKPCBQ=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710084625-dd05ebf6ceb9/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710085335-ead6543d95f9 h1:zJ+33DKEA6CObPii5c5l5IbUIws31+Ni5NzzC3oYRLw=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710085335-ead6543d95f9/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710085810-8173216e9574 h1:Ha0d/sv/MzC3ASCTXfe2tAFJieLNJmTCBL8aETEOY14=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230710085810-8173216e9574/go.mod h1:rn6NA28Mej+qgLNx/Bu2wsdGyIycmacqlNP6gUXX2a0=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230801051747-b501160efc3b h1:yV1cBeu0GFxkDD6TDxzKv/rM3OMtyt1JXpeqDF5IO3Y=
repositories.action2quare.com/ayo/gocommon v0.0.0-20230801051747-b501160efc3b/go.mod h1:PdpZ16O1czKKxCxn+0AFNaEX/0kssYwC3G8jR0V7ybw=

15
main.go
View File

@ -2,7 +2,9 @@ package main
import ( import (
"context" "context"
"math/rand"
"net/http" "net/http"
"time"
"repositories.action2quare.com/ayo/gocommon" "repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/flagx" "repositories.action2quare.com/ayo/gocommon/flagx"
@ -19,29 +21,26 @@ func main() {
flagx.Parse() flagx.Parse()
logger.Println("build revision =", revision) logger.Println("build revision =", revision)
rand.Seed(time.Now().UnixNano())
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel()
mg, err := core.New(ctx) mg, err := core.New(ctx)
if err != nil { if err != nil {
logger.Error("core.New failed :", err) logger.Error("core.New failed :", err)
return panic(err)
} }
defer mg.Destructor()
serveMux := http.NewServeMux() serveMux := http.NewServeMux()
if err := mg.RegisterHandlers(ctx, serveMux, *prefix); err != nil { if err := mg.RegisterHandlers(ctx, serveMux, *prefix); err != nil {
logger.Error("RegisterHandlers failed :", err) logger.Error("RegisterHandlers failed :", err)
return panic(err)
} }
server := gocommon.NewHTTPServer(serveMux) server := gocommon.NewHTTPServer(serveMux)
logger.Println("maingate is started") logger.Println("maingate is started")
if err := server.Start(); err != nil { if err := server.Start(); err != nil {
logger.Error("maingate is stopped with error :", err) logger.Error("maingate is stopped with error :", err)
} }
cancel()
logger.Println("maingate is terminated") mg.Destructor()
} }

12
make_maingate_package.ps1 Normal file
View File

@ -0,0 +1,12 @@
# $ErrorActionPreference = 'SilentlyContinue'
$CurBranch = git branch --show-current
Remove-Item maingate.zip -Force -Recurse -ErrorAction SilentlyContinue
$Env:GOOS="linux"
$Env:GOARCH="amd64"
go build -ldflags="-s -w" .
Compress-Archive -Path maingate -Update -DestinationPath maingate.zip
Compress-Archive -Path *-firebase-*.json -Update -DestinationPath maingate.zip

File diff suppressed because one or more lines are too long