feature/dockerize-server
into develop
2 years ago
@ -0,0 +1,137 @@ | |||
package Friends_test | |||
import ( | |||
"bytes" | |||
"encoding/base64" | |||
"encoding/json" | |||
"fmt" | |||
"net/http" | |||
"testing" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Tests" | |||
) | |||
func Test_AcceptFriendRequest(t *testing.T) { | |||
client, ts, err := Tests.InitTestEnv() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u, err := Database.GetUserByUsername("test") | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u2, err := Tests.InitTestCreateUser("test2") | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
key, err := Seeder.GenerateAesKey() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
decodedPublicKey := Seeder.GetPubKey() | |||
encPublicKey, err := key.AesEncrypt([]byte(Seeder.PublicKey)) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
friendReq := Models.FriendRequest{ | |||
UserID: u.ID, | |||
FriendID: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u2.ID.String()), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendUsername: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u2.Username), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendPublicAsymmetricKey: base64.StdEncoding.EncodeToString( | |||
encPublicKey, | |||
), | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(key.Key, decodedPublicKey), | |||
), | |||
} | |||
err = Database.CreateFriendRequest(&friendReq) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
friendReqResponse := Models.FriendRequest{ | |||
UserID: u2.ID, | |||
FriendID: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u.ID.String()), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendUsername: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u.Username), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendPublicAsymmetricKey: base64.StdEncoding.EncodeToString( | |||
encPublicKey, | |||
), | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(key.Key, decodedPublicKey), | |||
), | |||
} | |||
jsonStr, _ := json.Marshal(friendReqResponse) | |||
req, _ := http.NewRequest( | |||
"POST", | |||
fmt.Sprintf( | |||
"%s/api/v1/auth/friend_request/%s", | |||
ts.URL, | |||
friendReq.ID, | |||
), | |||
bytes.NewBuffer(jsonStr), | |||
) | |||
req.Header.Set("Content-Type", "application/json") | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusNoContent { | |||
t.Errorf("Expected %d, recieved %d", http.StatusNoContent, resp.StatusCode) | |||
return | |||
} | |||
var reqs []Models.FriendRequest | |||
err = Database.DB.Find(&reqs).Error | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
for _, r := range reqs { | |||
if r.AcceptedAt.Valid != true { | |||
t.Errorf("Expected true, recieved false") | |||
return | |||
} | |||
} | |||
} |
@ -0,0 +1,204 @@ | |||
package Friends_test | |||
import ( | |||
"bytes" | |||
"encoding/base64" | |||
"encoding/json" | |||
"net/http" | |||
"testing" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Tests" | |||
) | |||
func Test_CreateFriendRequest(t *testing.T) { | |||
client, ts, err := Tests.InitTestEnv() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u, err := Database.GetUserByUsername("test") | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u2, err := Tests.InitTestCreateUser("test2") | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
key, err := Seeder.GenerateAesKey() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
decodedPublicKey := Seeder.GetPubKey() | |||
encPublicKey, err := key.AesEncrypt([]byte(Seeder.PublicKey)) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
friendReq := Models.FriendRequest{ | |||
UserID: u.ID, | |||
FriendID: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u2.ID.String()), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendUsername: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u2.Username), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendPublicAsymmetricKey: base64.StdEncoding.EncodeToString( | |||
encPublicKey, | |||
), | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(key.Key, decodedPublicKey), | |||
), | |||
} | |||
jsonStr, _ := json.Marshal(friendReq) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/auth/friend_request", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("Content-Type", "application/json") | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusOK { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
var r Models.FriendRequest | |||
err = Database.DB.First(&r).Error | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if r.AcceptedAt.Valid == true { | |||
t.Errorf("Expected false, recieved true") | |||
return | |||
} | |||
} | |||
func Test_CreateFriendRequestQrCode(t *testing.T) { | |||
client, ts, err := Tests.InitTestEnv() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u, err := Database.GetUserByUsername("test") | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u2, err := Tests.InitTestCreateUser("test2") | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
key, err := Seeder.GenerateAesKey() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
decodedPublicKey := Seeder.GetPubKey() | |||
encPublicKey, err := key.AesEncrypt([]byte(Seeder.PublicKey)) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
friendReq := Models.FriendRequest{ | |||
UserID: u.ID, | |||
FriendID: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u2.ID.String()), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendUsername: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u2.Username), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendPublicAsymmetricKey: base64.StdEncoding.EncodeToString( | |||
encPublicKey, | |||
), | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(key.Key, decodedPublicKey), | |||
), | |||
} | |||
friendReq2 := Models.FriendRequest{ | |||
UserID: u2.ID, | |||
FriendID: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u.ID.String()), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendUsername: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey( | |||
[]byte(u.Username), | |||
decodedPublicKey, | |||
), | |||
), | |||
FriendPublicAsymmetricKey: base64.StdEncoding.EncodeToString( | |||
encPublicKey, | |||
), | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(key.Key, decodedPublicKey), | |||
), | |||
} | |||
jsonStr, _ := json.Marshal([]Models.FriendRequest{friendReq, friendReq2}) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/auth/friend_request/qr_code", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("Content-Type", "application/json") | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusOK { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
var r Models.FriendRequest | |||
err = Database.DB.First(&r).Error | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if r.AcceptedAt.Valid == false { | |||
t.Errorf("Expected true, recieved false") | |||
return | |||
} | |||
} |
@ -1,60 +0,0 @@ | |||
package Friends | |||
import ( | |||
"encoding/json" | |||
"io/ioutil" | |||
"net/http" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Util" | |||
) | |||
func FriendRequest(w http.ResponseWriter, r *http.Request) { | |||
var ( | |||
user Models.User | |||
requestBody []byte | |||
requestJson map[string]interface{} | |||
friendID string | |||
friendRequest Models.FriendRequest | |||
ok bool | |||
err error | |||
) | |||
user, err = Util.GetUserById(w, r) | |||
if err != nil { | |||
http.Error(w, "Not Found", http.StatusNotFound) | |||
return | |||
} | |||
requestBody, err = ioutil.ReadAll(r.Body) | |||
if err != nil { | |||
http.Error(w, "Not Found", http.StatusNotFound) | |||
return | |||
} | |||
json.Unmarshal(requestBody, &requestJson) | |||
if requestJson["id"] == nil { | |||
http.Error(w, "Invalid Data", http.StatusBadRequest) | |||
return | |||
} | |||
friendID, ok = requestJson["id"].(string) | |||
if !ok { | |||
http.Error(w, "Error", http.StatusInternalServerError) | |||
return | |||
} | |||
friendRequest = Models.FriendRequest{ | |||
UserID: user.ID, | |||
FriendID: friendID, | |||
} | |||
err = Database.CreateFriendRequest(&friendRequest) | |||
if requestJson["id"] == nil { | |||
http.Error(w, "Error", http.StatusInternalServerError) | |||
return | |||
} | |||
w.WriteHeader(http.StatusNoContent) | |||
} |
@ -0,0 +1,74 @@ | |||
package Messages | |||
import ( | |||
"encoding/json" | |||
"io/ioutil" | |||
"net/http" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"github.com/gorilla/mux" | |||
) | |||
type rawChangeMessageExpiry struct { | |||
MessageExpiry string `json:"message_expiry"` | |||
} | |||
// ChangeUserMessageExpiry handles changing default message expiry for user | |||
func ChangeConversationMessageExpiry(w http.ResponseWriter, r *http.Request) { | |||
var ( | |||
// user Models.User | |||
changeMessageExpiry rawChangeMessageExpiry | |||
conversationDetail Models.ConversationDetail | |||
requestBody []byte | |||
urlVars map[string]string | |||
detailID string | |||
ok bool | |||
err error | |||
) | |||
urlVars = mux.Vars(r) | |||
detailID, ok = urlVars["detailID"] | |||
if !ok { | |||
http.Error(w, "Not Found", http.StatusNotFound) | |||
return | |||
} | |||
conversationDetail, err = Database.GetConversationDetailByID(detailID) | |||
if err != nil { | |||
http.Error(w, "Not Found", http.StatusNotFound) | |||
return | |||
} | |||
// Ignore error here, as middleware should handle auth | |||
// TODO: Check if user in conversation | |||
// user, _ = Auth.CheckCookieCurrentUser(w, r) | |||
requestBody, err = ioutil.ReadAll(r.Body) | |||
if err != nil { | |||
http.Error(w, "Error", http.StatusInternalServerError) | |||
return | |||
} | |||
err = json.Unmarshal(requestBody, &changeMessageExpiry) | |||
if err != nil { | |||
http.Error(w, "Error", http.StatusInternalServerError) | |||
return | |||
} | |||
err = conversationDetail.MessageExpiryDefault.Scan(changeMessageExpiry.MessageExpiry) | |||
if err != nil { | |||
http.Error(w, "Error", http.StatusUnprocessableEntity) | |||
return | |||
} | |||
err = Database.UpdateConversationDetail( | |||
&conversationDetail, | |||
) | |||
if err != nil { | |||
http.Error(w, "Error", http.StatusInternalServerError) | |||
return | |||
} | |||
w.WriteHeader(http.StatusNoContent) | |||
} |
@ -0,0 +1,16 @@ | |||
FROM golang:1.19-alpine | |||
RUN mkdir -p /go/src/git.tovijaeschke.xyz/Capsule/Backend | |||
COPY ./ /go/src/git.tovijaeschke.xyz/Capsule/Backend | |||
WORKDIR /go/src/git.tovijaeschke.xyz/Capsule/Backend | |||
# For "go test" | |||
RUN apk add gcc libc-dev | |||
RUN go mod download | |||
RUN go build -o /go/bin/capsule-server main.go | |||
CMD [ "/go/bin/capsule-server" ] |
@ -0,0 +1,70 @@ | |||
package Models | |||
import ( | |||
"database/sql/driver" | |||
"errors" | |||
) | |||
// MessageExpiry holds values for how long messages should expire by default | |||
type MessageExpiry []uint8 | |||
const ( | |||
// MessageExpiryFifteenMin expires after 15 minutes | |||
MessageExpiryFifteenMin = "fifteen_min" | |||
// MessageExpiryThirtyMin expires after 30 minutes | |||
MessageExpiryThirtyMin = "thirty_min" | |||
// MessageExpiryOneHour expires after one hour | |||
MessageExpiryOneHour = "one_hour" | |||
// MessageExpiryThreeHour expires after three hours | |||
MessageExpiryThreeHour = "three_hour" | |||
// MessageExpirySixHour expires after six hours | |||
MessageExpirySixHour = "six_hour" | |||
// MessageExpiryTwelveHour expires after twelve hours | |||
MessageExpiryTwelveHour = "twelve_hour" | |||
// MessageExpiryOneDay expires after one day | |||
MessageExpiryOneDay = "one_day" | |||
// MessageExpiryThreeDay expires after three days | |||
MessageExpiryThreeDay = "three_day" | |||
// MessageExpiryNoExpiry never expires | |||
MessageExpiryNoExpiry = "no_expiry" | |||
) | |||
// MessageExpiryValues list of all expiry values for validation | |||
var MessageExpiryValues = []string{ | |||
MessageExpiryFifteenMin, | |||
MessageExpiryThirtyMin, | |||
MessageExpiryOneHour, | |||
MessageExpiryThreeHour, | |||
MessageExpirySixHour, | |||
MessageExpiryTwelveHour, | |||
MessageExpiryOneDay, | |||
MessageExpiryThreeDay, | |||
MessageExpiryNoExpiry, | |||
} | |||
// Scan new value into MessageExpiry | |||
func (e *MessageExpiry) Scan(value interface{}) error { | |||
var ( | |||
strValue = value.(string) | |||
m string | |||
) | |||
for _, m = range MessageExpiryValues { | |||
if strValue != m { | |||
continue | |||
} | |||
*e = MessageExpiry(strValue) | |||
return nil | |||
} | |||
return errors.New("Invalid MessageExpiry value") | |||
} | |||
// Value gets value out of MessageExpiry column | |||
func (e MessageExpiry) Value() (driver.Value, error) { | |||
return string(e), nil | |||
} | |||
func (e MessageExpiry) String() string { | |||
return string(e) | |||
} |
@ -1,105 +1,33 @@ | |||
package Models | |||
import ( | |||
"database/sql/driver" | |||
"errors" | |||
"github.com/gofrs/uuid" | |||
"gorm.io/gorm" | |||
) | |||
// BeforeUpdate prevents updating the email if it has not changed | |||
// BeforeUpdate prevents updating the username or email if it has not changed | |||
// This stops a unique constraint error | |||
func (u *User) BeforeUpdate(tx *gorm.DB) (err error) { | |||
if !tx.Statement.Changed("Username") { | |||
tx.Statement.Omit("Username") | |||
} | |||
return nil | |||
if !tx.Statement.Changed("Email") { | |||
tx.Statement.Omit("Email") | |||
} | |||
// MessageExpiry holds values for how long messages should expire by default | |||
type MessageExpiry []uint8 | |||
const ( | |||
// MessageExpiryFifteenMin expires after 15 minutes | |||
MessageExpiryFifteenMin = "fifteen_min" | |||
// MessageExpiryThirtyMin expires after 30 minutes | |||
MessageExpiryThirtyMin = "thirty_min" | |||
// MessageExpiryOneHour expires after one hour | |||
MessageExpiryOneHour = "one_hour" | |||
// MessageExpiryThreeHour expires after three hours | |||
MessageExpiryThreeHour = "three_hour" | |||
// MessageExpirySixHour expires after six hours | |||
MessageExpirySixHour = "six_hour" | |||
// MessageExpiryTwelveHour expires after twelve hours | |||
MessageExpiryTwelveHour = "twelve_hour" | |||
// MessageExpiryOneDay expires after one day | |||
MessageExpiryOneDay = "one_day" | |||
// MessageExpiryThreeDay expires after three days | |||
MessageExpiryThreeDay = "three_day" | |||
// MessageExpiryNoExpiry never expires | |||
MessageExpiryNoExpiry = "no_expiry" | |||
) | |||
// MessageExpiryValues list of all expiry values for validation | |||
var MessageExpiryValues = []string{ | |||
MessageExpiryFifteenMin, | |||
MessageExpiryThirtyMin, | |||
MessageExpiryOneHour, | |||
MessageExpiryThreeHour, | |||
MessageExpirySixHour, | |||
MessageExpiryTwelveHour, | |||
MessageExpiryOneDay, | |||
MessageExpiryThreeDay, | |||
MessageExpiryNoExpiry, | |||
} | |||
// Scan new value into MessageExpiry | |||
func (e *MessageExpiry) Scan(value interface{}) error { | |||
var ( | |||
strValue = value.(string) | |||
m string | |||
) | |||
for _, m = range MessageExpiryValues { | |||
if strValue != m { | |||
continue | |||
} | |||
*e = MessageExpiry(strValue) | |||
return nil | |||
} | |||
return errors.New("Invalid MessageExpiry value") | |||
} | |||
// Value gets value out of MessageExpiry column | |||
func (e MessageExpiry) Value() (driver.Value, error) { | |||
return string(e), nil | |||
} | |||
func (e MessageExpiry) String() string { | |||
return string(e) | |||
} | |||
// User holds user data | |||
type User struct { | |||
Base | |||
Username string `gorm:"not null;unique" json:"username"` | |||
Password string `gorm:"not null" json:"password"` | |||
ConfirmPassword string `gorm:"-" json:"confirm_password"` | |||
Email string ` json:"email"` | |||
AsymmetricPrivateKey string `gorm:"not null" json:"asymmetric_private_key"` // Stored encrypted | |||
AsymmetricPublicKey string `gorm:"not null" json:"asymmetric_public_key"` | |||
SymmetricKey string `gorm:"not null" json:"symmetric_key"` // Stored encrypted | |||
AttachmentID *uuid.UUID ` json:"attachment_id"` | |||
Attachment Attachment ` json:"attachment"` | |||
MessageExpiryDefault MessageExpiry `gorm:"default:no_expiry" json:"-" sql:"type:ENUM( | |||
'fifteen_min', | |||
'thirty_min', | |||
'one_hour', | |||
'three_hour', | |||
'six_hour', | |||
'twelve_hour', | |||
'one_day', | |||
'three_day' | |||
)"` // Stored encrypted | |||
MessageExpiryDefault MessageExpiry `gorm:"default:no_expiry" json:"-" sql:"type:ENUM('fifteen_min', 'thirty_min', 'one_hour', 'three_hour', 'six_hour', 'twelve_hour', 'one_day', 'three_day', 'no_expiry')"` // Stored encrypted | |||
} |
@ -0,0 +1,8 @@ | |||
#!/bin/sh | |||
while true; do | |||
go build main.go | |||
./main & | |||
PID=$! | |||
inotifywait -r -e modify . | |||
kill $PID | |||
done |
@ -1 +1,2 @@ | |||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" | |||
#include "Generated.xcconfig" |
@ -1 +1,2 @@ | |||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" | |||
#include "Generated.xcconfig" |
@ -0,0 +1,41 @@ | |||
# Uncomment this line to define a global platform for your project | |||
# platform :ios, '11.0' | |||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. | |||
ENV['COCOAPODS_DISABLE_STATS'] = 'true' | |||
project 'Runner', { | |||
'Debug' => :debug, | |||
'Profile' => :release, | |||
'Release' => :release, | |||
} | |||
def flutter_root | |||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) | |||
unless File.exist?(generated_xcode_build_settings_path) | |||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" | |||
end | |||
File.foreach(generated_xcode_build_settings_path) do |line| | |||
matches = line.match(/FLUTTER_ROOT\=(.*)/) | |||
return matches[1].strip if matches | |||
end | |||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" | |||
end | |||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) | |||
flutter_ios_podfile_setup | |||
target 'Runner' do | |||
use_frameworks! | |||
use_modular_headers! | |||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) | |||
end | |||
post_install do |installer| | |||
installer.pods_project.targets.each do |target| | |||
flutter_additional_ios_build_settings(target) | |||
end | |||
end |
@ -0,0 +1,59 @@ | |||
PODS: | |||
- Flutter (1.0.0) | |||
- FMDB (2.7.5): | |||
- FMDB/standard (= 2.7.5) | |||
- FMDB/standard (2.7.5) | |||
- image_picker_ios (0.0.1): | |||
- Flutter | |||
- MTBBarcodeScanner (5.0.11) | |||
- path_provider_ios (0.0.1): | |||
- Flutter | |||
- qr_code_scanner (0.2.0): | |||
- Flutter | |||
- MTBBarcodeScanner | |||
- shared_preferences_ios (0.0.1): | |||
- Flutter | |||
- sqflite (0.0.2): | |||
- Flutter | |||
- FMDB (>= 2.7.5) | |||
DEPENDENCIES: | |||
- Flutter (from `Flutter`) | |||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) | |||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) | |||
- qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`) | |||
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) | |||
- sqflite (from `.symlinks/plugins/sqflite/ios`) | |||
SPEC REPOS: | |||
trunk: | |||
- FMDB | |||
- MTBBarcodeScanner | |||
EXTERNAL SOURCES: | |||
Flutter: | |||
:path: Flutter | |||
image_picker_ios: | |||
:path: ".symlinks/plugins/image_picker_ios/ios" | |||
path_provider_ios: | |||
:path: ".symlinks/plugins/path_provider_ios/ios" | |||
qr_code_scanner: | |||
:path: ".symlinks/plugins/qr_code_scanner/ios" | |||
shared_preferences_ios: | |||
:path: ".symlinks/plugins/shared_preferences_ios/ios" | |||
sqflite: | |||
:path: ".symlinks/plugins/sqflite/ios" | |||
SPEC CHECKSUMS: | |||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 | |||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a | |||
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb | |||
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb | |||
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 | |||
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e | |||
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad | |||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 | |||
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 | |||
COCOAPODS: 1.11.3 |